Java包装类是否真的不可变?

时间:2010-11-07 12:58:04

标签: java wrapper

Java Wrapper类应该是不可变的。这意味着一旦创建了一个对象,例如

Integer i = new Integer(5);

其价值无法改变。但是,做

i = 6;

完全有效。

那么,这种背景下的不变性是什么意思呢? 这与自动装箱/拆箱有关吗? 如果是这样,有没有办法阻止编译器这样做?

谢谢

6 个答案:

答案 0 :(得分:27)

i是一个参考。您的代码会将引用i更改为指向另一个同样不可变的Integer

final Integer i = Integer.valueOf(5);

可能更有用。

答案 1 :(得分:18)

不可变意味着无法更改对象状态。在您的情况下,您没有更改对象new Integer(5),但您已将引用i更改为指向另一个对象。希望很清楚:)

答案 2 :(得分:13)

编译器自动装箱原始值,这意味着

Integer value = 6;

将编译为

Integer value = Integer.valueOf(6);

Integer.valueOf将返回具有给定值的Integer实例。在你的情况下i现在将引用Integer(6)而不是Integer(5),Integer(5)对象本身不会改变。

要看到这一点,您可以执行以下操作

Integer i = new Integer(5);//assign new integer to i
Integer b = i;//b refences same integer as i
i = 6;//modify i
System.out.println(i +"!="+b);

这将打印6!=5,如果整数实例已被修改,则会打印6!=6

澄清这只是为了说明对Integer的赋值如何仅修改引用并且不会改变Integer实例本身。用户@KNU指出它不能证明或显示Integer的不变性,据我所知,不变性只是间接由于其API中缺少修改方法以及Integer.valueOf返回的实例必须要求缓存一定范围。

答案 3 :(得分:5)

i = 6的作用原因是自动装箱正在拦截并将其变为i = new Integer(6)。因此,正如@Peter所说,你现在指的是一个新对象。

答案 4 :(得分:0)

Integer i = new Integer(5);
i++;                         // i  will become 6

其中i++i = new Integer( i.intValue() + 1);相同

答案 5 :(得分:-1)

java中的所有包装类都是不可变的。创建后,我们无法更改包装类对象的值。请阅读Why Strings and wrapper classes are immutable in java?以获取更多信息。