先来看个有意思的题目:
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就没什么奇怪的了