差点被遗忘的“局部变量”和“引用传递”

今天被一个小伙伴的问题差点问来闷起,起因是代码如下:

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哈哈~

猜你喜欢

转载自www.cnblogs.com/getwind/p/12176981.html