Java 更改引用但不更改对象本身?

Java changes reference but not the object itself?

请看下面代码:

public static void main(String[] args)
{
    Test t1 = new Test();
    t1.i = 1;
    Test t0 = t1;
    Test t2 = new Test();
    t2.i = 2;
    t0 = t2; 
    System.out.println(t1.i); //prints 1, I thought it would print 2
}

在我通过简单的赋值从其他地方获得 t1 对象后,有没有办法改变它而不直接访问 t1? (即 t1 = t0)

你在这里不明白的是,当做 t0 = t2 时,你用 [=] 的引用替换了当时与 t1 相同的 t0 的地址引用15=] 所以不,它不会影响 t1

但是,t0.i 会打印 2。

但是要回答你的问题

Is there any way to change t1 object after I got it from somewhere else by simple assignment without accessing t1 directly? (i.e. t1 = t0)

是的,有办法,检查这个片段

Test t1 = new Test();
t1.i = 1;
Test t0 = t1;
t0.i = 3;
System.out.println(t1.i); //prints 3

这会将 t1.i 修改为 3 访问 t0.i

如果你想使用t2对象,那么你可以直接修改i的值:

Test t1 = new Test();
t1.i = 1;
Test t0 = t1;
Test t2 = new Test();
t2.i = 2;
t0.i = t2.i; 
System.out.println(t1.i); //prints 2
Test t1 = new Test();
t1.i = 1

可以表示为

            +-------+
            | Test  |
t1 -------> +-------+
            | i (1) |
            +-------+

现在当你做

Test t0 = t1;

您分配给 t0 的值与 t1 中的值相同,这意味着现在它们具有相同的值(同一测试实例的地址),所以您的情况是

            +-------+
t1 ----+    | Test  |
       +--> +-------+
t0 ----+    | i (1) |
            +-------+

现在在这段代码之后

Test t2 = new Test();
t2.i = 2;

你将拥有

            +-------+
t1 ----+    | Test  |
       +--> +-------+
t0 ----+    | i (1) |
            +-------+

            +-------+
            | Test  |
t2 -------> +-------+
            | i (2) |
            +-------+

当你这样做时

t0 = t2; 

你把你的情况改成

            +-------+
t1 ----+    | Test  |
       +--> +-------+
            | i (1) |
t0 ----+    +-------+
       |
       |    +-------+
       |    | Test  |
t2 ----+--> +-------+
            | i (2) |
            +-------+

所以正如您现在所见,t0 持有与 t2 引用持有的对象相同的对象,但 t1 引用未更改,这就是为什么

System.out.println(t1.i)

打印 1

这是您的程序及其功能的说明。系统的每个状态以虚线分隔显示。

请注意当您执行 t0 = t1 时会发生什么。您假设这意味着从现在开始,t0t1 是同义词——只要您使用一个,另一个就会受到影响。但实际上,t0t1只是对同一个对象的两个引用。

t0 进行新分配只是将其从 "blue" 对象中分离出来,并将其 re-attached 分配给 "violet" 对象。

只要 t0t1 都指向同一个对象,您对其指向的对象(例如 t0.i = 5)的内容所做的任何更改都会被看到通过另一个引用,因为它们都引用同一个对象。但是一旦您将其他内容分配给 t0,它就会失去与 t1 的连接。在你这样做之后,更改它会反映在指向相同的 "violet" 对象的 t2 中,而不是仍然指向旧的 "blue" 对象的 t1 中.

所以:

  • 如果您为引用分配一个新值 - 它不再指向与以前相同的对象,并且之前的任何 "double referencing" 都将丢失。
  • 如果您为引用的内容分配一个新值,它将反映在查看同一对象的所有引用变量中。