精华内容
下载资源
问答
  • Java编程中,当对象作为参数传递给方法时候,是按引用传递的,但是有的人会说这实质上是按值传递的。其实两者说的都不错,只是理解的方式不一样罢了,二者的原理其实是一样的。

    一、

    Java编程中,当对象作为参数传递给方法时候,是按引用传递的,但是有的人会说这实质上是按值传递的。其实两者说的都不错,只是理解的方式不一样罢了,二者的原理其实是一样的。


    二、

    下面通过一个例子来详细说明Java对象作为方法参数的时候会出现的情况:

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 测试java的引用传值
     *
     * Created by Xuyh at 2017/01/05 上午 10:27.
     */
    public class SetParamTest {
    	public static void main(String... args) {
    		// 集合对象,列表[a, b, c]
    		List<String> testParam = new ArrayList<String>();
    		testParam.add("a");
    		testParam.add("b");
    		testParam.add("c");
    		System.out.println("Old: " + testParam.toString() + "\r\n");
    
    		// 引用(地址)传值,并直接修改testParam指向对象的值
    		change(testParam);
    		System.out.println("Change1: " + testParam.toString() + "\r\n");
    
    		testParam.add("a");
    
    		// 引用(地址)传值,修改指向对象之后再将地址返回
    		testParam = change2(testParam);
    		System.out.println("Change2: " + testParam.toString() + "\r\n");
    
    		// 集合对象变为[b, c, d, e]
    		testParam.add("d");
    		testParam.add("e");
    
    		// 引用(地址)传值,方法内部new新集合对象并将地址赋给方法局部参数,
    		// 并不改变testParam的值,testParam仍然指向原地址
    		sort(testParam);
    		System.out.println("sort1: " + testParam.toString() + "\r\n");
    		// 引用(地址)传值,方法内部new新集合对象并将地址赋给方法局部参数,
    		// 并将新地址返回,再赋值给testParam,因此testParam指向的对象发生改变
    		testParam = sort2(testParam);
    		System.out.println("sort2: " + testParam.toString() + "\r\n");
    	}
    
    	public static void change(List<String> param) {
    		if (param.contains("a"))
    			param.remove("a");
    	}
    
    	public static List<String> change2(List<String> param) {
    		if (param.contains("a"))
    			param.remove("a");
    		return param;
    	}
    
    	public static void sort(List<String> param) {
    		List<String> newParam = new ArrayList<String>();
    		for (int i = param.size() - 1; i >= 0; i--) {
    			newParam.add(param.get(i));
    		}
    		param = newParam;
    	}
    
    	public static List<String> sort2(List<String> param) {
    		List<String> newParam = new ArrayList<String>();
    		for (int i = param.size() - 1; i >= 0; i--) {
    			newParam.add(param.get(i));
    		}
    		return newParam;
    	}
    }
    

    上面的例子简单的说就是一个列表,[a, b, c],首先通过两个方法把其中的字符”a”去除,然后通过两个方法对列表[b, c, d, e]进行倒序排序。同时在操作的过程中不断将main方法中的testParam输出出来。


    接着请看程序运行的结果:

    Old: [a, b, c]
    
    Change1: [b, c]
    
    Change2: [b, c]
    
    sort1: [b, c, d, e]
    
    sort2: [e, d, c, b]

    由结果可以看到,两个change方法都将原来的testParam改变了,而sort方法只有一个改变了testParam的值,这个有趣的现象接下来要好好说说了。下面从四个比较典型的方法来介绍不同情况下对象作为值传入方法时候内存中的情况,以便我们更好理解java的方法传值原理。


    三、

    change方法

    public static void change(List<String> param) {
    	if (param.contains("a"))
    		param.remove("a");
    }

    testParam作为参数传递给param时候,内存内是这样的:


    testParam的地址值复制给了change方法局部变量param,于是param指向了与testParam相同的一个对象。注意这时候param的引用(地址)值是testParam的一份拷贝。

     

    Change方法中将列表的”a”元素去除时候的情况是这样的:


    此时testParamparam指向的对象(同一个)发生了改变,所以方法执行完毕之后输出testParam是发生改变的。



    change2方法

    public static List<String> change2(List<String> param) {
    	if (param.contains("a"))
    		param.remove("a");
    	return param;
    }

    change方法类似,当对象在方法中发生改变时候,内存中的情况是这样的:


    testParam = change2(testParam);

    方法执行到最后,param会返回,也就是param的引用(地址)值会返回,然后又拷贝给testParam(其实是多此一举,二者的地址值完全相同)。所以方法执行完成之后输出的testParam是发生改变的。



    sort方法

    public static void sort(List<String> param) {
    	List<String> newParam = new ArrayList<String>();
    	for (int i = param.size() - 1; i >= 0; i--) {
    		newParam.add(param.get(i));
    	}
    	param = newParam;
    }

    调用方法时候内存中是这样的


    接着,方法中new了一个新的对象,并在处理排序之后将新对象的引用(地址)赋值给param,这时候内存中的情况是这样的:


    可以看到,testParamparam指向的已经不是同一个地址了,并且testParam指向的对象仍然没有发生改变。因此方法执行完毕之后输出的结果看来,sort方法是没有用的。



    sort2方法

    public static List<String> sort2(List<String> param) {
    	List<String> newParam = new ArrayList<String>();
    	for (int i = param.size() - 1; i >= 0; i--) {
    		newParam.add(param.get(i));
    	}
    	return newParam;
    }

    sort方法类似,执行sort2方法前内存中是这样的:


    新对象排序完成后是这样的:


    这时候testParamparam都是指向原来的对象

    方法的最后把newParam返回,即将newParam的引用(地址)值返回,在main方法中将其赋值给testParam

    testParam = sort2(testParam);

    然后内存中就是这样的了:



    因此经过返回后的sort2方法是有作用的。



    四、

    小结:

    通过以上的分析可以得出,Java中对象作为方法参数传递的是对象引用(地址)值的拷贝,通俗的讲,就是拷贝了一把钥匙,main方法中的钥匙跟被调用方法中参数的钥匙对应能打开的房间是相同的,但是是不同的钥匙。如果在被调用方法中,参数钥匙被修改了(new了一个新对象并赋值给参数钥匙),不会影响main方法钥匙指向的房间。这点是值得注意的。

     

    因此如果想要在被调用方法中不修改参数指向的对象,可以通过new一个新的对象来实现,但是如果想要new一个新的对象并使main方法该对象变成这个新的对象,就要将其作为返回值返回并赋值给旧对象变量了。




























    展开全文
  • 关于Java对象作为参数传递是传值还是传引用的问题

    万次阅读 多人点赞 2016-09-06 22:37:20
    前言 在Java中,当对象作为参数传递时,究竟传递的是对象的值,还是对象的引用,这是一个饱受争议的话题。若传的是值,那么函数接收的只是实参的一个副本,函数对形参的操作并不会对实参产生影响;若传的是引用,...

    前言

      在Java中,当对象作为参数传递时,究竟传递的是对象的值,还是对象的引用,这是一个饱受争议的话题。若传的是值,那么函数接收的只是实参的一个副本,函数对形参的操作并不会对实参产生影响;若传的是引用,那么此时对形参的操作则会影响到实参。
      首先我们来看一句代码:

    Object obj = new Object();
    

      这句话的意思是:创建一个Object对象,再创建一个名为obj的引用,让这个引用指向这个对象,如下图所示:

      1.png-4.3kB

    在有了上面的基础之后,我们便来看下面这组在网上很流行的例子:

    基本数据类型作为参数传递:

    例1:

    public class test {
        public static void main(String[] args) {
            int i = 1;
            System.out.println("before change, i = "+i);
            change(i);
            System.out.println("after change, i = "+i);
        }
        public static void change(int i){
            i = 5;
        }
    }
    

      这个例子不难理解,当基本数据类型作为参数传递时,传递的是实参值的副本,即传的是值,无论在函数中怎么操作这个副本,实参的值是不会被改变的。所以以上代码执行的结果是:
      
      before change, i = 1
      after change, i = 1
      
      

    对象作为参数传递:

      在下面的例2中,我们把StringBuffer对象作为参数传递到change函数。
      
      例2:

    public class test {
        public static void main(String[] args) {
            StringBuffer sb = new StringBuffer("Hello ");
            System.out.println("before change, sb is "+sb.toString());
            change(sb);
            System.out.println("after change, sb is "+sb.toString());
        }
        public static void change(StringBuffer stringBuffer){
            stringBuffer.append("world !");
        }
    }
    

      为了方便推理出结论,我们先直接看程序的运行结果:
      
      before change, sb is Hello
      after change, sb is Hello world !
      
      从输出结果中我们可以发现,sb所指向的对象的值被改变了,那么是否我们可以推论出,在Java中,当对象作为参数传递时,传递的是该对象的引用呢?我们再来看下面这个例子:
      
      例3:

    public class test {
        public static void main(String[] args) {
            StringBuffer sb = new StringBuffer("Hello ");
            System.out.println("before change, sb is "+sb.toString());
            change(sb);
            System.out.println("after change, sb is "+sb.toString());
        }
        public static void change(StringBuffer stringBuffer){
            stringBuffer = new StringBuffer("Hi ");
            stringBuffer.append("world !");
        }
    }
    

      如果上面的推论是正确的,即Java中对象作为参数传递,实际传递的是该对象的引用,那么在调用change函数之后,原对象的值应该是会改变的,变为“Hi world !”,但是,当我们运行程序后,结果却是如下所示:
      
      before change, sb is Hello
      after change, sb is Hello
      
      原对象的值并没有被改变,这与上面的推论相矛盾!为什么在Java中,当对象作为参数传递时,有的时候实参被改变了,而有的时候实参并未被改变呢?下面让我们来分析一下其中的原因:
      从文章的开头我们知道,当执行StringBuffer sb = new StringBuffer(“Hello “)时,我们创建了一个指向新建对象“new StringBuffer(“Hello “)”的引用“sb”,如下图所示:
      
      2.png-3.2kB
      
      在例2中,当我们调用change函数后,实际上,形参stringBuffer也指向了实参sb所指向的对象,即:
      
      3.png-6.3kB
      
      那么当我们执行stringBuffer.append(“world !”)后,便通过对象的引用“stringBuffer”修改了对象的值,使之变成了“Hello world !”,即:
      
      4.png-6.6kB
      
      但是,在例3中的change函数中,我们又新建了一个对象“new StringBuffer(“Hi “)”(这实际上在内存中开辟了一块在原对象地址之外的新区域),这让形参stringBuffer实际指向了这个新建的对象,并将新对象的值设置为“Hi world !”,即:
      
      image_1art4suka65r1m4o1a0spgcjr89.png-10.1kB
      
      那么我们就不难理解,为何在执行完change函数之后,实参的值仍为“Hello”了。
      

    结论

      综上所述,我们可以得出结论:在Java中,当对象作为参数传递时,实际上传递的是一份“引用的拷贝”。
      
      

    展开全文
  • Java中接口对象作为参数传递

    千次阅读 2016-05-23 18:56:14
    Java中接口对象作为参数传递(小例子)


           

         第一步想用接口作为参数 首要的条件就是要有接口,定义一个接口

    <pre name="code" class="java">         public interface A{
                  public void helloWorld();
             }

    
    

         第二步:有了接口,必须有实现接口的类

    <pre name="code" class="java">               public class B implements A{
                        public void helloWorld(){
                        System.out.println("世界,您好!");
                        }
                   }


    
         第三步:有了前边的准备工作当然就要有将A接口作为参数的类了
    

    <pre name="code" class="java">             public class C {
                         public void helloTest (A a){
                                a.helloWorld();
    
                        }
            
                     }


    
          第四步:就是客户端的调用了

    public class Client{
         public static void main(String[] args){
          C   c = new C();
    //向上转型
          A  b  = new B();
    
           c.helloWorld(b);
    
          }
    }

       第五步:程序结果

    世界,您好!
    展开全文
  • java中String对象作为参数传递问题

    千次阅读 2020-06-03 15:24:04
    java中将对象作为参数传递究竟是值传递还是引用传递? 1、基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的。 2、对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了...

    问题

    java中将对象作为参数传递究竟是值传递还是引用传递?
    1、基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的。
    2、对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。

    且看下面代码
    首先我们有一个Student类,它有两个成员变量nameage

    package test_code;
    public class Student {
        String name;
        int age;
        public Student(String name,int age){
            this.name = name;
            this.age = age;
        }
    }
    

    Student对象进行参数传递,运行如下代码

    package test_code;
    public class method_test {
        public static void main(String[] args) {
            Student s = new Student("jack",16);
            test(stu);
            System.out.println(stu.age);
        }
        public static void test(Student s)
        {
            s.age = 22;
        }
    }
    

    请问输出是16还是22呢?
    答案是22,因为对象进行参数传递时是将对象的地址拷贝了一份传给s,也就是说方法中的s和传入的stu指向的是同一个对象,通过s.age将值进行修改了那么stu.age的值也相应被修改了。这很容易理解。


    那么当String类对象进行参数传递时,运行如下代码

    package test_code;
    public class method_test {
        public static void main(String[] args) {
            String str = "111";
            test(str);
            System.out.println(str);
        }
        public static void test(String s)
        {
            System.out.println(s);
            s = "222";
            System.out.println(s);
        }
    }
    

    请问输出是什么呢?
    答案是222吗?不对。
    那么为什么答案是111呢?
    问题就在s = "222";这一行上。
    这一行执行后,s和str所指向的对象就不是一个了。为什么呢?
    由于Java中String对象不可改变的特性,这里其实是在常量池中新开辟了一块区域给222使用,s指向了222,但是并没有改变str的指向,那么str自然是111了。

    本文较为简单,但希望能够大家带来一定的启发,大家在工作学习中一定要多多思考,欢迎关注,一起进步。

    展开全文
  • java中的参数传递(只有值传递没有引用传递)

    万次阅读 多人点赞 2019-07-31 19:25:14
    Java中只有传值调用(值传递),没有传址调用(址传递或者引用传递)。所以在java方法中改变参数的值是不会改变原变量的值的,但为什么改变引用变量的属性值却可以呢?请看下面的解答。 java中的数据类型 Java中...
  • java对象作为参数传递给一个方法,到底是值传递,还是引用传递? pdd:所谓java只有按值传递:基本类型 值传递;引用类型,地址值传递,所以叫值传递。  当主函数的变量,对象(主本)传递到副函数时,传递的...
  • java 对象作为方法的参数传递

    万次阅读 2018-03-24 14:45:25
    说到对象作为方法的参数传递的时候,大家都知道,当方法有返回值的时候,我们在其他方法定义一个接收他的对象就把他的值给获取到了,可是如果不定义对象接收呐?请看方法有返回值的情况下:这种情况下,打印出来的值...
  • java对象作为参数传递一般是引用传递,基本变量传值方式是值传递。但是字符串作为一个对象传递却意外的是值传递。 先定义值传递意义:就是讲原先的基本变量或者引用拷贝一份,作为参数传递给函数。特点是当函数...
  • JAVA在方法中对象作为参数传递

    千次阅读 2018-02-23 17:42:35
    但是在java中,将方法A中的某个对象传递到方法B中进行修改后,再返回到A中,我们会发现对象在B中的修改在A中也有效。示例代码如下:有一个bean类:public class DemoBean { private String id; pu...
  • 这样是改变不了a的指向的,然后我理解了java是只有值传递,所以相当于这个传的A a被复制了一份,改变的指向,是改变的复制的指向,所以原来的没有变 然后: Class b { A a } void foo(B b) { b.a =new B(); } main...
  • java中把对象作为参数传递的理解

    万次阅读 2017-12-29 14:24:12
    只不过,当把对象作为参数传递时,可以通过该副本引用改变该对象的的属性。 而我上面程序在方法里 issuePublishDate = null; 这里已经对变量重新赋值了。此时的变量 issuePublishDate 已经不再是参数传进来的那个...
  • 问:当一个对象被当做参数传递到一个方法后,此方法可改变这个对象的属性,并返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递。在java语言中只有值传递参数;当一个对象实例作为一个参数被...
  • JAVA接口作为参数传递

    万次阅读 多人点赞 2011-07-20 18:02:55
    可以将接口类型的参数作为方法参数,在实际是使用时可以将实现了接口的类传递给方法,后方法或按照重写的原则执行,实际调用的是实现类中的方法代码体,这样便根据传进入的参数的不同而实现不同的功能。重要的是,当...
  • java方法接收一个对象,修改该对象是否影响调用方
  • Java对象,对象引用,参数传递

    千次阅读 2018-07-01 19:45:46
    Java中,万物皆对象! 比如定义一个学生类 public class Student { private int id; private String name; private int age; public Student() { // TODO Auto-generated constructor stub su...
  • Java对象作为参数传递给一个方法时,实际上传递的是这个对象引用的拷贝,被拷贝的引用和拷贝的引用指向同一个内存地址,即同一个对象 所以如果在方法中改变参数引用(拷贝的引用)指向的内存地址,对方法外的引用是...
  • 传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值。 引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应...
  • 对象作为参数传递给方法

    千次阅读 2018-12-06 16:55:06
    //新建一个对象c1接收返回的c System.out.println(i+"\t"+c1.getArea()); } } public void gettime(){ Circle c=new Circle(); Scanner sc=new Scanner(System.in); System.out.println("请输入time")...
  • java中的参数传递-值传递、引用传递

    千次阅读 2017-04-12 16:38:05
    参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递。 在 Java 应用程序中永远不会传递对象,而只传递对象引用。因此是按引用传递对象Java 应用程序按引用传递对象这一事实...
  • 基本数据类型 整型:byte,short,int,long浮点型:float,double字符型:char布尔型:boolean引用数据类型 数组对象(类、接口)一般情况下,基本数据类型传递时是值传递,引用数据类型是引用传递。而String有些不...
  • java之给方法传递对象参数

    千次阅读 2016-03-29 01:20:29
    java中给方法传递对象参数,和传递数组一样,传递对象实际上是传递对象的引用。 包括package的用法。 javac Jpro\Circes3.java javac Jpro\Demo032902.java java Jpro.Demo032902
  • Java中的参数传递

    万次阅读 多人点赞 2018-01-19 13:52:15
    传引用参数指的还是原来的那个引用,但是Java里面参数类型是对象时是复制了原来的引用到一块新的内存,两者之间没有关系 1:按值传递是什么 指的是在方法调用时,传递参数是按值的拷贝传递。示例如下: ...
  • Java接口之作为参数传递

    千次阅读 2013-03-25 22:06:31
    学习java的人都知道,java是一个面向对象的编程语言。 但经过一段时间的学习,你还可以体会到其实java就是一个面 向接口的编程,最主要的原因就是接口可以直接体现出java的 继承、 多态(最主要的),那好接下来...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 511,695
精华内容 204,678
关键字:

java对象作为参数传递

java 订阅