将一个原始变量分配给另一个与将引用变量分配给另一个
Assigning one primitive variable to another vs a reference variable to another
我想了解原始变量和对象引用变量的行为有何不同。我以 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");
}
}
在上面的代码中,我在更改 b
的值之前和之后获取了 a = 10;
的值。
原始变量情况的输出是:
a = 10
a = 10 after change it to b and b is 30
但是,在对象引用变量中,一旦我更改 b1.height = 30;
的值,我就会得到一个不同的值
参考变量案例的输出是:
a1.height = 10
a1.height = 30 after change to b1
书中提到,在这两种情况下都会复制位模式并放置一个新副本。如果这是真的,那为什么我们会得到不同的行为?
只有一个实例
当你说
Dimension b1= a1; // <-- assigns reference of a1 to b1.
您将a1
指向的引用地址分配给b1
。因此,当您通过 b1
修改 height
字段时,您也修改了 a1
.
b1.height=30; // <-- a1.height = 30
创建另一个实例
如果你想让b1
成为一个唯一的引用,那么你使用new
。
Dimension b1= new Dimension(a1.width, a1.height); // <-- creates a new Dimension
这是引用和基元之间的根本区别。在这两种情况下,您都会获得实际的 值,但只有在对象的情况下,您才有机会影响它的任何其他用法的结果。
让我们看一下代码。
int a = 10;
int b = a;
这两个声明是这样说的:
- 将值 10 分配给名为
a
的 int 标识符。
- 将
a
的值分配给名为 b
的 int 标识符。
到目前为止,还不错。我们没有在任何地方说 a
被 b
引用;我们只取值。
如果我们声明:
b = 30;
我们说 取值 30 并将其分配给标识符 b
。
那时我们不对 a
做任何事情;它已经包含值 10
。这就是 a
和 b
不同的原因。
现在,当我们到达对象时,表面上并没有真正改变...
Dimension a1 = new Dimension(5, 10);
Dimension b1 = a1;
我们翻译成:
- 将具有 (int) 参数 5 和 10 的新 Dimension 的实例化值分配给
Dimension
标识符 a1
。
- 将
a1
的值分配给 Dimension
标识符 b1
。
我们仍在此处分配 值,因为 Java 是 pass-by-value。这里的问题在于,在 Java 中,对象的值仍然是对该对象的引用。
通过上面的例子,a1
和b1
指向同一个实例。
现在,当我们这样说时:
b1.height = 30;
我们实际上是在说:
- 将值 30 分配给通过值
b1
. 取消引用的字段 height
我们在这里仍然指的是 b1
的值,它与 a1
相关联。这就是您看到差异的原因;因为 a1
和 b1
引用相同的值(即相同的引用),所以通过标识符 b1
所做的任何更改都会通过 a1
.
反映出来
我想了解原始变量和对象引用变量的行为有何不同。我以 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");
}
}
在上面的代码中,我在更改 b
的值之前和之后获取了 a = 10;
的值。
原始变量情况的输出是:
a = 10
a = 10 after change it to b and b is 30
但是,在对象引用变量中,一旦我更改 b1.height = 30;
参考变量案例的输出是:
a1.height = 10
a1.height = 30 after change to b1
书中提到,在这两种情况下都会复制位模式并放置一个新副本。如果这是真的,那为什么我们会得到不同的行为?
只有一个实例
当你说
Dimension b1= a1; // <-- assigns reference of a1 to b1.
您将a1
指向的引用地址分配给b1
。因此,当您通过 b1
修改 height
字段时,您也修改了 a1
.
b1.height=30; // <-- a1.height = 30
创建另一个实例
如果你想让b1
成为一个唯一的引用,那么你使用new
。
Dimension b1= new Dimension(a1.width, a1.height); // <-- creates a new Dimension
这是引用和基元之间的根本区别。在这两种情况下,您都会获得实际的 值,但只有在对象的情况下,您才有机会影响它的任何其他用法的结果。
让我们看一下代码。
int a = 10;
int b = a;
这两个声明是这样说的:
- 将值 10 分配给名为
a
的 int 标识符。 - 将
a
的值分配给名为b
的 int 标识符。
到目前为止,还不错。我们没有在任何地方说 a
被 b
引用;我们只取值。
如果我们声明:
b = 30;
我们说 取值 30 并将其分配给标识符 b
。
那时我们不对 a
做任何事情;它已经包含值 10
。这就是 a
和 b
不同的原因。
现在,当我们到达对象时,表面上并没有真正改变...
Dimension a1 = new Dimension(5, 10);
Dimension b1 = a1;
我们翻译成:
- 将具有 (int) 参数 5 和 10 的新 Dimension 的实例化值分配给
Dimension
标识符a1
。 - 将
a1
的值分配给Dimension
标识符b1
。
我们仍在此处分配 值,因为 Java 是 pass-by-value。这里的问题在于,在 Java 中,对象的值仍然是对该对象的引用。
通过上面的例子,a1
和b1
指向同一个实例。
现在,当我们这样说时:
b1.height = 30;
我们实际上是在说:
- 将值 30 分配给通过值
b1
. 取消引用的字段
height
我们在这里仍然指的是 b1
的值,它与 a1
相关联。这就是您看到差异的原因;因为 a1
和 b1
引用相同的值(即相同的引用),所以通过标识符 b1
所做的任何更改都会通过 a1
.