先来看个有意思的题目:
1 public class Test { 2 public static void main(String args[]){ 3 StringBuilder test = new StringBuilder("aa"); 4 Change(test); 5 System.out.println(test.toString()); 6 } 7 8 private static void Change(StringBuilder test) { 9 test = new StringBuilder("bb"); 10 } 11 }
这里的输出是多少呢?对,输出为:aa ^_^
再看一个题目:
1 public class Test { 2 public static void main(String args[]){ 3 Person test = new Person(); 4 test.setId(123); 5 Change(test); 6 System.out.println(test.getId()); 7 } 8 9 private static void Change(Person test) { 10 test.setId(456); 11 } 12 }
这里的输出又是多少呢?对啦,就是:456 ^_^
还有一个:
1 public class Test { 2 public static void main(String args[]){ 3 Person test = new Person(); 4 test.setId(123); 5 Person newTest = test; 6 Change(test); 7 System.out.println(newTest.getId()); 8 } 9 10 private static void Change(Person test) { 11 test.setId(456); 12 } 13 }
这里的输出又是多少呢?还是:456 ^_^
看了上面几个小题目,可能有点同学就要说太easy,简直是小case,拿这种题来考我,嘛意思吗!!!
其实真正知道并能说出来龙去脉的,我问了我周围的同学,都是“就是这样嘛,……”,“知道结果不久完了吗……”
看来还是有不少同学对java中参数的问题含含糊糊的哦。
在java中,只要我们在传参时把握:"对象传引用,基本类型传值",就能解释上面的问题了。
在第1题中,test被初始化为StringBuilder对象实例的引用,test为一个引用,指向"aa",下一行,调用了方法change(StringBuilder test),这时test作为change()方法参数,被传递到方法中,在change()方法中,将传进来的参数指向了一个新的对象实例StringBuilder("bb"),即test-->"bb",但是并没有改变原来的对象"aa",在change()方法结束后也没有返回修改,故在change()中的参数随着方法结束就被释放了(相当于外派人员test干了一些老板"aa"不知道的事,没有报告给老板,故不会涨工资),此时作为main()方法的参数,test还是有效的引用,即指向"aa"的引用,所以打印出来的结果是aa。
在第2题中,test被初始化为Person对象实例的引用,并修改这个实例id的值为123,下一行,调用change(Person test)方法,test被作为实参传递到方法中,并对这个引用所指向的对象的实例的内容(即id属性)做出了修改,在change()方法结束后,change()方法中的参数test依然被释放,但是在该方法的作用范围内,修改了Person对象实例的内容。在main方法中依然保持着这个引用即test,此时打印结果当然就是被修改过的Person对象实例的Id的值456。
在第3题中,将test赋给newTest,此时两个引用指向的是同一个对象的实例。故打印结果为456就没什么奇怪的了