我做了两个测试,第一个从 Strings
开始
String str1 = "old";
String str2 = str1;
str1 = "new";
System.out.println(str1); //new
System.out.println(str2); //old
上面的例子表示str2 = str1, by value
现在我进行类似的操作,但这次使用 Lists
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = list1;
list1.add(1);
System.out.println(list1.size()); //1
System.out.println(list2.size()); //1
这个例子表示list2 = list1, by reference
我很困惑,哪些Java变量/对象
是通过value
传递的,哪些是通过reference
传递的?
最佳答案
在你的第一个代码中,是的,这一行
String str2 = str1;
分配 str2
同样String
由 str1
推荐, 即 "old"
.此时,它们是同一个对象。然而,下一行
str1 = "new";
创建 String
的新实例, 并更改 str1
的引用到这个新字符串。因为我们正在更改 str1
的引用, str2
的内容没有改变。
注意Java,String
s 是不可变的,即一旦初始化就不能改变状态。这样想,"old"
的内容可能永远不会改变。所以当你分配 "new"
至 str1
,您不更改 "old"
的值, 你创建了一个新的 String
相反。
换句话说,这里的这一行是一样的
str1 = new String("new");
http://i.minus.com/jboQoqCxApSELU.png
然而,在第二个代码中,
List<Integer> list2 = list1;
制作list2
请参阅与 list1
相同的列表.结果,list1
和 list2
引用同一个列表。然后
list1.add(1);
将元素添加到 list1
引用的列表中.然而,正如我所说,list1
和 list2
引用同一个列表,都是list1
和 list2
现在有元素 1
.方法调用中没有创建新实例。
http://i.minus.com/jxDLyBqcUzgHZ.png
事实上,如果你要这样做
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = list1;
list1 = new ArrayList<Integer>();
list1.add(1);
System.out.println(list1.size()); //1
System.out.println(list2.size()); //0
因为list1 = new ArrayList<Integer>();
重新分配 list1
到一个新列表,不再引用 list2
引用的对象.
毕竟赋值运算符(即obj1 = obj2
)总是复制引用,这两个引用在赋值后仍将引用同一个对象实例。这适用于 String
, List
,或任何其他类(但不是原始类型)。
然而,str1 = "new"
在大多数情况下,将创建 String
的新实例然后将引用分配给新的 String
至 str1
- 这是 Java 语言中的特例。这不适用于任何其他类型的对象。这不同于任何其他方法调用,如 list1.add(1)
.
关于java - 在 Java 中设置为相等 : by value or reference?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22188690/