public class TestVO {
public static void main(String[] args) {
VO vo1 = new VO();
VO vo2 = new VO();
VO vo3;
VO vo4 = new VO();
vo1.setName("Sourav");
vo2.setName("Anil");
vo3 = vo1;
vo4 = vo1;
System.out.println(" " + vo4.getName());
vo1.setName("Abhishek.");
System.out.println(vo1.getName() + " " + vo2.getName() + " " + vo3.getName() + " " + vo4.getName());
}
}
- OUTPUT是:---
Sourav
Abhishek. Anil Abhishek. Abhishek.
VO是一个包含字符串名称的简单类,包含 getter 和 setter 。
在第一个 System.out.println * vo4.getName() * print: Sourav ok。没关系。
但是在第二个 System.out.println * vo4.getName() * print: Abhishek。
我的问题是为什么第二次印刷是 Abhishek。。我在vo4对象中保留了vo1对象的副本而不是引用。这意味着它创造了一个新的记忆。 vo1和vo4是不同的。那么为什么vo4.getName在第二次更改。我正在设置vo1对象但是vo4会自动更改。它为什么会发生?
答案 0 :(得分:24)
我在vo4对象中保留了vo1对象的副本而不是引用。
不,您已将变量vo1
和vo4
指向相同的对象,如下所示:
+-----+ | vo1 |--------\ +-----+ \ +----------------+ --->| (object) | +-----+ / | name = Abishek | | vo4 |--------/ +----------------+ +-----+
让我们按照以下代码进行操作:
VO vo1 = new VO();
给我们:
+-----+ +----------------+ | vo1 |------------->| (object) | +-----+ | name = null | +----------------+
然后:
VO vo2 = new VO();
现在我们有:
+-----+ +----------------+ | vo1 |------------->| (object) | +-----+ | name = null | +----------------+ +-----+ +----------------+ | vo2 |------------->| (object) | +-----+ | name = null | +----------------+
然后:
VO vo3;
...只使用vo3
创建null
(不指向任何对象)。
然后:
VO vo4 = new VO();
所以我们有:
+-----+ +----------------+ | vo1 |------------->| (object) | +-----+ | name = null | +----------------+ +-----+ +----------------+ | vo2 |------------->| (object) | +-----+ | name = null | +----------------+ +-----+ | vo3 | (is null) +-----+ +-----+ +----------------+ | vo4 |------------->| (object) | +-----+ | name = null | +----------------+
现在:
vo1.setName("Sourav");
vo2.setName("Anil");
给我们:
+-----+ +----------------+ | vo1 |------------->| (object) | +-----+ | name = Sourav | *** change is here *** +----------------+ +-----+ +----------------+ | vo2 |------------->| (object) | +-----+ | name = Anil | *** and here *** +----------------+ +-----+ | vo3 | (is null) +-----+ +-----+ +----------------+ | vo4 |------------->| (object) | +-----+ | name = null | +----------------+
这是事情变得有趣的地方:
vo3 = vo1;
vo4 = vo1;
同一个对象vo3
上的点vo1
指向该对象的点vo4
,释放对象vo4
曾经指向(有资格进行垃圾收集)。给我们:
+-----+ | vo1 |----\ +-----+ \ \ +-----+ \ +----------------+ | vo3 |------------->| (object) | +-----+ / | name = Sourav | / +----------------+ +-----+ / | vo4 |----/ +-----+ +-----+ +----------------+ | vo2 |------------->| (object) | +-----+ | name = Anil | +----------------+
现在
System.out.println(" " + vo4.getName());
...按照你的期望给我们“Sourav”。
然后
vo1.setName("Abhishek.");
...更改vo1
,vo3
和vo4
都指向的对象:
+-----+ | vo1 |----\ +-----+ \ \ +-----+ \ +----------------+ | vo3 |------------->| (object) | +-----+ / | name = Abishek | / +----------------+ +-----+ / | vo4 |----/ +-----+ +-----+ +----------------+ | vo2 |------------->| (object) | +-----+ | name = Anil | +----------------+
...所以getName()
,vo1
或vo3
vo4
会给你“Abishek。”
答案 1 :(得分:6)
因为vo1和vo4都指的是同一个对象。
以下赋值使vo4引用由vo1引用的对象。
vo4 = vo1;
因此,任何引用(无论是vo1还是vo4)对引用对象所做的任何更改都将反映在同一个对象中。
因此,如果你更改说vo4.setName(“xyz”),它将改变由vo4引用的对象,但实际上vo1也指的是同一个对象。因此,在为一个对象分配的一个内存位置进行更改,该对象由许多引用(在本例中为vo1和vo4)引用。
答案 2 :(得分:2)
您正在为vo1
和vo4
分配相同的对象引用。
vo4 = vo1;
现在两个引用变量都指向同一个对象。
答案 3 :(得分:1)
Object是一个实体,它将为其中定义的字段存储实际值。将使用new
关键字在内存中创建对象,并且引用将返回到引用变量。引用变量不是对象。
因此,在您的示例中,new VO()
将在堆内存上创建对象,VO1
将引用它。
答案 4 :(得分:0)
当您执行vo4 = vo1;
时,只需通过引用vo1
复制vo4
,换句话说,您可以执行指针分配,这样它们就会分配到内存中的相同位置,如果{ {1}}更改它也会影响vo1
,如您看到的结果
答案 5 :(得分:0)
除了基本数据类型之外,java中的所有内容都是指针。创建vo4
后,您将其设置为vo1
。现在vo4
指向v01
。
答案 6 :(得分:0)
执行vo4 = vo1
时,表示引用变量vo4
指的是vo1
引用的对象。因此,vo1
和vo4
都会引用同一个对象
阅读本教程的第一部分。你不需要直到最后,因为它是关于垃圾收集,但它详细解释了如何为对象分配参考以及如何对它们进行处理。
http://www.thejavageek.com/2013/06/22/how-do-objects-become-eligible-for-garbage-collection/
答案 7 :(得分:0)
我必须准备以下图片: 如你所见,vo1,Vo3,Vo4指向同一个对象