java传值还是传地址问题

参见英文答案 > Is Java “pass-by-reference” or “pass-by-value”?       

我有以下两种与ArrayList get方法相关的情况,一种是自定义类,另一种是String类:

1.下面是修改Custom类ArrayList元素的示例:

ArrayList mTmpArray1 = new ArrayList();

MyClass myObj1 = new MyClass(10);

mTmpArray1.add(myObj1);

MyClass myObj2 = mTmpArray1.get(0);

myObj2.myInt = 20;

MyClass myObj3 = mTmpArray1.get(0);

Log.d(TAG, "Int Value:"+myObj3.myInt); // Prints "20"

2.以下是修改String ArrayList元素的示例:

ArrayList mTmpArray2 = new ArrayList();

mTmpArray2.add("Test_10");

String myStr1 = mTmpArray2.get(0);

myStr1 = "Test_20";

String myStr2 = mTmpArray2.get(0);

Log.d(TAG, "Str Value:"+myStr2); // Prints "Test_10"

所以在MyClass ArrayList的情况下,当我调用get并修改值时,我看到当我再次获得时,变化正在反映.

但是当我修改String ArrayList时,同样的方式也没有反映出变化.

1、两种方案中get方法的不同之处是什么?

2、是在String的情况下,String类创建深层副本并返回新对象,并且在Custom类的情况下创建浅层副本?

3、在适用于“LinkedHashMap”,“HashMap”和“List”的第一个场景中?

解决方法:

在这两种情况下,你没有做同样的事情.

在这里更新对象的状态,因此更改会影响列表中存储的对象:

myObj2.myInt = 20;

在这里,您要为局部变量分配一个新对象,因此列表不受影响:

myStr1 = "Test_20";

如果String是可变的,您可以通过调用某个方法修改String,并且更改将反映在列表中存储的对象中:

myStr1.setSomething(...);

另一方面,如果在第一种情况下您将更改局部变量的值,则列表中存储的对象不会受到影响:

myObj2 = new MyClass (...);

感觉和java函数传值有异曲同工的意思。当为基本类型及包装类时为传值,当为自定义类及其他高级List、Map等时为传地址。

来源: https://codeday.me/bug/20190528/1171158.html
 

posted @ 2021-06-10 16:38  Mr.zzz  阅读(39)  评论(0编辑  收藏  举报