来自Java in a Nutshell, 2.10 Reference Types,
Java不直接操作对象和数组。相反,它 操纵对象和数组的引用。因为Java处理 通过引用,类和数组类型的对象和数组被称为 参考类型。相反,Java处理基元的值 直接或按价值类型。
但是从下面看,原始包装类(对象)实际上是由值而不是引用来处理的,
> Integer foo = new Integer(1);
> Integer bar = foo;
> bar = new Integer(2);
> foo
1
上面的引用不是很正确吗?
更新:我的困惑来自误解我上面的代码段与以下内容之间的区别:
> import java.util.LinkedList;
> LinkedList<Integer> foo = new LinkedList<Integer>();
> foo.add(1);
> LinkedList<Integer> bar = foo;
> bar.remove();
> System.out.println(foo.size());
0
> System.out.println(bar.size());
0
在后一种情况下,bar.remove()
实际上对foo
和bar
引用的LinkedList进行操作。
答案 0 :(得分:1)
原始类包装器是对象引用,而不是基本类型。
在您的示例中,您为变量分配了一个新值,而不是更新状态。这就是为什么foo
保留其旧值(旧的因为它从未更改过)的原因:
Integer foo = new Integer(1);
Integer bar = foo; //bar and foo "points" to the same location
bar = new Integer(2); //now bar only "points" to a new location, foo is unaffected
System.out.println(foo);
您可以使用==
和equals
比较轻松地对此进行测试:
Integer a = 128;
Integer b = 128;
System.out.println(a == b); //false
System.out.println(a.equals(b)); //true
答案 1 :(得分:1)
您的代码片段并未证明包装器的行为类似于值类型:实际上,它们是引用类型,并且它们是不可变的。
Integer foo = new Integer(1); // foo references an object wrapping 1
Integer bar = foo; // bar references the same object as foo
bar = new Integer(2); // bar references an object wrapping 2;
// continues to reference 1
查看原始包装器会发生什么的一种简单方法是使用==
运算符而不是调用equals
来比较它们的相等性。但是,您需要小心避免比较小数字的包装器,因为它们是出于性能原因而被缓存的。
答案 2 :(得分:0)
您链接的引用是指字段访问和数组访问表达式。那些需要通过参考值来确定底层对象。
=
运算符称为assignment operator.在您的情况下,它不是字段访问表达式,也不是数组访问表达式,因此我们将归入第三种情况
- 首先,评估左侧操作数以产生变量。如果此评估突然完成,则为赋值表达式 因同样的原因突然完成;右手操作数不是 评估并且没有分配。
- 否则,将评估右侧操作数。如果此评估突然完成,则赋值表达式突然完成 出于同样的原因,没有任何转让。
- 否则,将右侧操作数的值转换为左侧变量的类型,进行值集转换 (§5.1.13)到适当的标准值集(不是 扩展指数值集),转换结果是 存储在变量中。
所以在
bar = new Integer(2);
评估bar
并生成变量本身。然后,必须评估new Integer(2)
。那是new instance creation expression。它生成一个值为reference value
参考值(通常只是引用)是指向这些的指针 对象,以及一个特殊的空引用,它不引用任何对象。
生成该值后,会将其分配给bar
。
请注意foo
从未参与过。