Java Wrapper类应该是不可变的。这意味着一旦创建了一个对象,例如
Integer i = new Integer(5);
其价值无法改变。但是,做
i = 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?以获取更多信息。