我想了解原始和对象引用变量的行为方式有何不同。我使用了Kathy Sierra的 OCA / OCP Java SE7 中的以下代码作为示例:
public class VariableTesting {
public static void main(String[] args) {
int a = 10;
System.out.println("a= " + a);
int b = a;
b = 30;
System.out.println("a= " + a + " after change it to b and b is " + b);
Dimension a1 = new Dimension(5, 10);
System.out.println("a1.height = " + a1.height);
Dimension b1 = a1;
b1.height = 30;
System.out.println("a1.height= " + a1.height + " after change to b1");
}
}
在上面这段代码中,我在更改a = 10;
的值之前和之后得到b
的值。
原始变量大小写的输出是:
a = 10
a = 10 after change it to b and b is 30
但是,在对象引用变量I中,一旦我更改b1.height = 30;
参考变量案例的输出是:
a1.height = 10
a1.height = 30 after change to b1
书中提到,在这两种情况下都会复制位模式并放置新的副本。如果这是真的,那么为什么我们会得到不同的行为?
答案 0 :(得分:5)
这是引用和基元之间的基础差异。在这两种情况下,您都获得了实际的值,但只有在对象的情况下,您才有可能影响其他任何用法的结果。
让我们来看看代码。
int a = 10;
int b = a;
这两个声明如下:
a
的a
的值分配给名为b
。到目前为止,这么好。我们没有说a
引用b
;我们只是在接受价值观。
如果我们声明:
b = 30;
我们说取值30并将其分配给标识符b
。
此时我们对a
没有做任何事情;它已包含值10
。这就是a
和b
不同的原因。
现在,当我们到达对象时,表面上的事情并没有真正改变......
Dimension a1 = new Dimension(5, 10);
Dimension b1 = a1;
我们将其翻译为:
Dimension
标识符a1
。a1
的值分配给Dimension
标识符b1
。我们仍然在这里分配值 ,因为Java是pass-by-value。这里的踢球者是在Java中,对象的值仍然是对该对象的引用。
通过上面的示例,a1
和b1
指向同一个实例。
现在,当我们陈述:
b1.height = 30;
我们实际上在说:
height
取消引用的字段b1
。我们仍然在这里提到b1
的值,它与a1
相关联。这就是你看到差异的原因;因为a1
和b1
引用相同的值(相同的引用),通过标识符b1
完成的任何更改都会通过a1
反映出来。
答案 1 :(得分:1)
当你说
时Dimension b1= a1; // <-- assigns reference of a1 to b1.
您将a1
引用的引用地址分配给 b1
。因此,当您通过height
修改b1
字段时,您也会修改a1
。
b1.height=30; // <-- a1.height = 30
如果您希望b1
成为唯一的引用,则使用new
。
Dimension b1= new Dimension(a1.width, a1.height); // <-- creates a new Dimension