关于OOP中的引用和值

时间:2014-06-01 11:57:07

标签: java reference

在这个程序中,circle_b的变量“r”或“m”指向对象circle_a的变量或者它们有一个值(没有指向另一个对象)??

class Circle
{
    public int r;
    public int m;

    public Circle(r, m)
    {
        this.r = r;
        this.m = m;
    }

    public getR() {return r;}
}


Main:
Circle circle_a = new Circle(10, 20);
Circle circle_b = new Circle(circle_a.getR(), circle_a.m);

编辑:

class MyClass {Integer var;}
MyClass a = new MyClass(); a.var = 5;
MyClass b = new MyClass(); b.var = a.var;

b.var指向a.var或具有自我价值(b.var = 5)?

2 个答案:

答案 0 :(得分:1)

使用int重新提出原始问题,它们具有值,而不是引用。使用Integer重新编辑,它是相同的答案(它们具有值,而不是引用),但有问题的值是对对象的引用。 (我稍后会详细介绍。)

每当你看到

a = b

...或

someMethod(a)

...您正在看到被复制。

对于像int这样的原语,这几乎就是我们需要说的。 : - )

当有问题的值引用一个对象时,它被称为“对象引用”。它仍然被复制,但两个副本继续引用(指向)同一个对象。

ASCII-art在这里有时很有用......

基元

此代码:

int a = 5;
int b = 0;

给我们:

+---+  +---+
| a |  | b |
+---+  +---+
| 5 |  | 0 |
+---+  +---+

如果我们这样做

b = a;

然后我们有:

+---+  +---+
| a |  | b |
+---+  +---+
| 5 |  | 5 |
+---+  +---+

对象引用

此代码:

Integer a = new Integer(5); // This is effectively what you did with your = 5;, the primitive gets promoted
Integer b = null;

给我们:

+-------+
|   a   |
+-------+         +--------------------+
| (ref) |-------->|                    |
+-------+         | The Integer object |
                  | primitive value: 5 |
                  |                    |
                  +--------------------+

+-------+
|   b   |
+-------+
| null  |
+-------+

如果我们这样做

b = a;

然后我们有:

+-------+
|   a   |
+-------+
| (ref) |---+     +--------------------+
+-------+   |     |                    |
            +---->| The Integer object |
                  | primitive value: 5 |
            +---->|                    |
+-------+   |     +--------------------+
|   b   |   |
+-------+   |
| (ref) |---/
+-------+

现在,使用Integer,几乎没有机会混淆,因为Integer个实例不可变:没有可以更改的状态信息(Integer原始值为42的实例将始终具有原始值42)。但是大多数类都有可变实例 - 即具有可以更改的状态信息的实例。

让我们考虑HashMap个实例,例如:

Map<String, String> a = new HashMap<String, String>();
Map<String, String> b = null;

给我们:

+-------+
|   a   |
+-------+         +--------------------+
| (ref) |-------->|                    |
+-------+         | The HashMap object |
                  | size: 0            |
                  |                    |
                  +--------------------+

+-------+
|   b   |
+-------+
| null  |
+-------+

如果我们这样做

b = a;

然后我们有:

+-------+
|   a   |
+-------+
| (ref) |---+     
+-------+   |     +--------------------+
            +---->|                    |
                  | The HashMap object |
            +---->| size: 0            |
+-------+   |     |                    |
|   b   |   |     +--------------------+
+-------+   |
| (ref) |---/
+-------+

一切都非常好。由于HashMap个实例可变ab都引用同一个对象,我们通过a对该对象所做的任何更改通过b引用可以看到引用,因为它们指向同一个对象。

所以,如果我们这样做:

a.put("foo", "bar");

我们得到:

+-------+
|   a   |
+-------+
| (ref) |---+     
+-------+   |     +--------------------+
            +---->|                    |
                  | The HashMap object |
            +---->| size: 1            |
+-------+   |     | "foo" = "bar"      |
|   b   |   |     |                    |
+-------+   |     +--------------------+
| (ref) |---/
+-------+

当然如此:

System.out.println(a.size()); // 1
System.out.println(b.size()); // 1

ab 变量仍然完全独立。如果您将值分配给b

b = new HashMap<String, String>();

你得到:

+-------+
|   a   |
+-------+         +----------------------------+
| (ref) |-------->|                            |
+-------+         | The first HashMap object   |
                  | size: 1                    |
                  | "foo" = "bar"              |
                  |                            |
                  +----------------------------+

+-------+
|   b   |
+-------+         +----------------------------+
| (ref) |-------->|                            |
+-------+         | A different HashMap object |
                  | size: 0                    |
                  |                            |
                  +----------------------------+

答案 1 :(得分:1)

这些变量是int,基元,它们只是作为值存储,请参阅doc