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

Pet*_*osB 20 java wrapper

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

Integer i = new Integer(5);
Run Code Online (Sandbox Code Playgroud)

它的价值无法改变.但是,干嘛

i = 6;
Run Code Online (Sandbox Code Playgroud)

完全有效.

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

谢谢

bma*_*ies 27

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

final Integer i = Integer.valueOf(5);
Run Code Online (Sandbox Code Playgroud)

可能更有用.


Pet*_*hev 18

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


jos*_*efx 13

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

Integer value = 6;
Run Code Online (Sandbox Code Playgroud)

将编译为

Integer value = Integer.valueOf(6);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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

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


dre*_*kka 5

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