java中的对象和引用之间的区别与代码?

时间:2013-07-12 07:51:30

标签: java

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会自动更改。它为什么会发生?

8 个答案:

答案 0 :(得分:24)

  

我在vo4对象中保留了vo1对象的副本而不是引用。

不,您已将变量vo1vo4指向相同的对象,如下所示:

+-----+
| 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.");

...更改vo1vo3vo4都指向的对象:

+-----+
| vo1 |----\
+-----+     \
             \
+-----+       \      +----------------+
| vo3 |------------->| (object)       |
+-----+       /      | name = Abishek |
             /       +----------------+
+-----+     /
| vo4 |----/
+-----+

+-----+              +----------------+
| vo2 |------------->| (object)       |
+-----+              | name = Anil    |
                     +----------------+

...所以getName()vo1vo3 vo4会给你“Abishek。”

答案 1 :(得分:6)

因为vo1和vo4都指的是同一个对象。

以下赋值使vo4引用由vo1引用的对象。

vo4 = vo1;

因此,任何引用(无论是vo1还是vo4)对引用对象所做的任何更改都将反映在同一个对象中。

因此,如果你更改说vo4.setName(“xyz”),它将改变由vo4引用的对象,但实际上vo1也指的是同一个对象。因此,在为一个对象分配的一个内存位置进行更改,该对象由许多引用(在本例中为vo1和vo4)引用。

答案 2 :(得分:2)

您正在为vo1vo4分配相同的对象引用。

vo4 = vo1;

现在两个引用变量都指向同一个对象。

enter image description here

答案 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引用的对象。因此,vo1vo4都会引用同一个对象

阅读本教程的第一部分。你不需要直到最后,因为它是关于垃圾收集,但它详细解释了如何为对象分配参考以及如何对它们进行处理。

http://www.thejavageek.com/2013/06/22/how-do-objects-become-eligible-for-garbage-collection/

答案 7 :(得分:0)

我必须准备以下图片: 如你所见,vo1,Vo3,Vo4指向同一个对象

enter image description here