今天被一个小伙伴的问题差点问来闷起,起因是代码如下:
public static void main(String[] args) {
List a = new ArrayList<>();
a.add("1");
a.add("2");
List b = new ArrayList<>();
testExchangeList(a,b);
System.out.println("a="+a); } private static void testExchangeList(List a, List b){ a=b; //想要将 b 集合的值赋给 a 集合
a.add("3"); System.out.println("testExchangeList a="+a);
}
结果为:
testExchangeList a=[3]
a=[1, 2]
b=[3]
问题是为什么方法中的参数为引用传递,但是 testExchangeList()方法中的赋值动作没有生效呢?
我还就顺着思路往下想了一会,怎么想都不对,觉得好像忽略了什么。
然后,重新温习了一下这一块的内容,就解释通了:
private static void testExchangeList(List a, List b){ a=b; //想要将 b 集合的值赋给 a 集合 System.out.println("testExchangeList a="+a); }
首先,方法体中局部变量和方法参数在jvm中的储存方法是相同的,都是在栈上开辟空间来储存的,随着进入方法开辟,退出方法回收。
也可以理解为方法参数等同于方法中的局部变量。
在调用 testExchangeList(List a,List b) 方法时,会先创建多2个局部变量 a 和 b ,
然后将传递过来的值赋值给 局部变量a 和 局部变量b ,此时的引用关系为:
但是当 testExchangeList() 方法中执行完 a=b 后,此为赋值操作,对于对象而言,就是将b的引用地址赋值给a,此时的引用关系就发生了变化:
此时 局部变量 a 的地址指向了局部变量 b 的地址,局部变量 b 的指向地址 和 变量 b 的地址是一样的。(后来一想,变量名称相同可能有点误导了我最开始的判断,哈哈哈^_^~~)
所以此时 操作局部变量 a ,就等于操作了main方法中变量 b 的值。但是main方法中变量 a 没有一点变化,
所以此时打印 局部变量 a 的结果应该为:
testExchangeList a = [ 3 ],也就是局部变量 b,也可以说变量 b 的值,
而此时的引用关系为:
当 testExchangeList()执行完后,局部变量消失,那么此后的引用关系就变成了这样:
所以在最后输出打印 集合 a 和 集合 b 时的结果就应该是:
a=[1, 2]
b=[3]
所以,所以,此 a 非彼 a,只是自己差点忘了最基础的东西,以此写出来就当复习巩固一下基础知识点。O(∩_∩)O哈哈~