先不多说,看两个题。
第一题,如下代码执行结果:
package com.zhyea.test; public class Test { public static void main(String[] args) { String str = "123"; changeString(str); System.out.println(str); } public static void changeString(String str){ str = "ABCDEFG"; } }
第二题,如下代码执行结果:
package com.zhyea.test; public class MyTest { public static void main(String[] args) { Person robin = new Person("Robin", 29);
changePersonName(robin, "zhangsan"); System.out.println(robin); } public static void changePersonName(Person p, String name) { p.setName(name); } } class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "Person name:[" + name + "], age:[" + age + "]"; } }
看后心里运行下,稍后讨论结果。
值传递:调用方法时,实参将它的值传递给形参,执行方法时形参值的改变不影响实参。
引用传递:也称地址传递。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
关于引用传递解释得有点晦涩是吧。不过也不影响理解。
这里传递的两个变量都是引用类型(String和Person)。所以按引用传递的解释,第一个输出的应该是“ABCDEFG”,第二个输出的就是“Person name:[zhangsan], age:[29]”。
嗯。跟我想的一样。可是我错了。
这个问题在CSDN有讨论过:http://bbs.csdn.net/topics/390245117。
直接说结论:Java中没有引用传递。Java中实参交给方法形参的值是它实际值的一个副本。方法对形参所做的任何操作对实参无任何影响。
回来说那两道题:
第一题结果比较好理解,和结论一致,不解释了。
第二题还需要解释下,在这道题中,实参的值并没有改变,改变的是实参的值所指向的对象里面的属性。解释得比较拗口。这涉及到引用类型与内存之间的一些关系。这个可以自己查些资料。
说下我的理解:如果把引用类型对象比作一个房子,那么引用类型的变量(实参)就是一把可以打开这个房子的门牌号。实参把房子的门牌号告诉了方法,方法知道了门牌号就可以找到并进入这个房子。但是哪怕方法把房子里的东西都搬空了,这个房子的门牌号却是不能动的。
再为第二题拿个实例出来就好理解了:
package com.zhyea.test; public class MyTest { public static void main(String[] args) { Person robin = new Person("Robin", 29); changePerson(robin); System.out.println(robin); } public static void changePerson(Person p) { Person tom = new Person("Tom", 16); p = tom; } } class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "Person name:[" + name + "], age:[" + age + "]"; } }
就这样。