在 Java 中设置相等:按值还是按引用? [英] Setting equal in Java: by value or reference?
问题描述
我做了两个测试,第一个以 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,String
s 是不可变的,即一旦初始化就不能改变状态.这样想,"old"
的内容可能永远不会改变.因此,当您将 "new"
分配给 str1
时,您不会更改 "old"
的值,而是创建了一个新的 字符串
代替.
Pay attention that Java, String
s 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");
http://i.minus.com/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.
http://i.minus.com/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 中设置相等:按值还是按引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!