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
时会发生什么。您假设这意味着从现在开始,t0
和 t1
是同义词——只要您使用一个,另一个就会受到影响。但实际上,t0
和t1
只是对同一个对象的两个引用。
对 t0
进行新分配只是将其从 "blue" 对象中分离出来,并将其 re-attached 分配给 "violet" 对象。
只要 t0
和 t1
都指向同一个对象,您对其指向的对象(例如 t0.i = 5
)的内容所做的任何更改都会被看到通过另一个引用,因为它们都引用同一个对象。但是一旦您将其他内容分配给 t0
,它就会失去与 t1
的连接。在你这样做之后,更改它会反映在指向相同的 "violet" 对象的 t2
中,而不是仍然指向旧的 "blue" 对象的 t1
中.
所以:
- 如果您为引用分配一个新值 - 它不再指向与以前相同的对象,并且之前的任何 "double referencing" 都将丢失。
- 如果您为引用的内容分配一个新值,它将反映在查看同一对象的所有引用变量中。
请看下面代码:
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
时会发生什么。您假设这意味着从现在开始,t0
和 t1
是同义词——只要您使用一个,另一个就会受到影响。但实际上,t0
和t1
只是对同一个对象的两个引用。
对 t0
进行新分配只是将其从 "blue" 对象中分离出来,并将其 re-attached 分配给 "violet" 对象。
只要 t0
和 t1
都指向同一个对象,您对其指向的对象(例如 t0.i = 5
)的内容所做的任何更改都会被看到通过另一个引用,因为它们都引用同一个对象。但是一旦您将其他内容分配给 t0
,它就会失去与 t1
的连接。在你这样做之后,更改它会反映在指向相同的 "violet" 对象的 t2
中,而不是仍然指向旧的 "blue" 对象的 t1
中.
所以:
- 如果您为引用分配一个新值 - 它不再指向与以前相同的对象,并且之前的任何 "double referencing" 都将丢失。
- 如果您为引用的内容分配一个新值,它将反映在查看同一对象的所有引用变量中。