我做了两个测试,第一个以 Strings
I did two tests, the first starting with Strings
String str1 = "old"; String str2 = str1; str1 = "new"; System.out.println(str1); //new System.out.println(str2); //old上面的例子表明str2 = str1, by value
现在我做类似的操作,但这次使用Lists
Now I do the similar operations, but this time with 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传递?
I am confused, which Java variables/objects are passed by value and which are passed by reference?
推荐答案在你的第一个代码中,是的,这一行
In your first code, yes, this line
String str2 = str1;将str2 赋值给str1 引用的同一个String,即"old".在这一点上,它们是同一个对象.但是,下一行
Assigns str2 to the same String referred by str1, that is, "old". At this point, they are the same object. However, the next line
str1 = "new";创建String 的new 实例,并将str1 的引用更改为这个新的String.由于我们改变了str1的引用,str2的内容没有改变.
create a new instance of String, and changes the reference of str1 to this new String. As we are changing the reference of str1, the content of str2 are not changed.
注意 Java,Strings 是不可变的,即一旦初始化就不能改变状态.这样想,"old" 的内容可能永远不会改变.因此,当您将 "new" 分配给 str1 时,您不会更改 "old" 的值,而是创建了一个新的 字符串代替.
Pay attention that Java, Strings are immutable i.e. cannot change state once initialized. Thinking this way, content of "old" may never change. So when you assign "new" to str1, you don't change the value of "old", you create a new String instead.
换句话说,这里的这一行与
In other words, this line, in here, is the same as
str1 = new String("new");i.minus/jboQoqCxApSELU.png
然而,在第二个代码中,
However, in the second code,
List<Integer> list2 = list1;使 list2 引用与 list1 相同的列表.因此,list1 和 list2 指的是同一个列表.那么
make list2 refer to the same list as list1. As a result, list1 and list2 refer to the same list. Then
list1.add(1);向由 list1 引用的列表添加一个元素.但是,正如我所说,list1 和 list2 指的是同一个列表,list1 和 list2 现在都有元素 1.方法调用中没有创建新实例.
adds an element to the list referred by list1. However, as I have said, list1 and list2 refer to same list, both list1 and list2 now have the element 1. There is no new instance created in the method call.
i.minus/jxDLyBqcUzgHZ.png
事实上,如果你要这样做
In fact, if you were to do
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(); 将 list1 重新分配给一个新列表,该列表不再引用 list2.
because list1 = new ArrayList<Integer>(); reassigns list1 to a new list, that no longer refer to the object referred by list2.
毕竟赋值运算符(即obj1 = obj2)总是复制引用,这两个引用仍然会引用同一个对象分配后的实例.这适用于String、List 或任何其他类(但不是原始类型).
After all the assignment operator (i.e. obj1 = obj2) always copy the references, which two references will still refer to the same object instance after the assignment. This is for both String, List, or any other classes (But not primitive types).
然而,在大多数情况下,str1 = "new" 会创建一个 String 的新实例,然后将引用分配给新的 String 到 str1 - 这是 Java 语言中的一个特例.这不适用于任何其他类型的对象.这与 list1.add(1) 等任何其他方法调用不同.
However, str1 = "new" will, in most cases, create a new instance of String and then assign the reference to the new String to str1 - this is a special case in the Java lanaguage. This don't apply to any other kind of objects. This is different to any other method call like list1.add(1).
更多推荐
在 Java 中设置相等:按值还是按引用?
发布评论