在 Java 中设置相等:按值还是按引用? [英] Setting equal in Java: by value or reference?

查看:17
本文介绍了在 Java 中设置相等:按值还是按引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了两个测试,第一个以 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";

创建Stringnew 实例,并将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");

http://i.minus.com/jboQoqCxApSELU.png

然而,在第二个代码中,

However, in the second code,

List<Integer> list2 = list1;

使 list2 引用与 list1 相同的列表.因此,list1list2 指的是同一个列表.那么

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 引用的列表添加一个元素.但是,正如我所说,list1list2 指的是同一个列表,list1list2 现在都有元素 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)总是复制引用,这两个引用仍然会引用同一个对象分配后的实例.这适用于StringList任何其他类(但不是原始类型).

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 的新实例,然后将引用分配给新的 Stringstr1 - 这是 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆