【发布时间】:2011-05-06 06:59:12
【问题描述】:
Java Wrapper 类应该是不可变的。这意味着一旦创建了一个对象,例如,
Integer i = new Integer(5);
它的值不能改变。但是,做
i = 6;
完全有效。
那么,在这种情况下,不变性是什么意思? 这与自动装箱/拆箱有关吗? 如果是这样,有什么办法可以阻止编译器这样做?
谢谢
【问题讨论】:
Java Wrapper 类应该是不可变的。这意味着一旦创建了一个对象,例如,
Integer i = new Integer(5);
它的值不能改变。但是,做
i = 6;
完全有效。
那么,在这种情况下,不变性是什么意思? 这与自动装箱/拆箱有关吗? 如果是这样,有什么办法可以阻止编译器这样做?
谢谢
【问题讨论】:
不可变意味着对象状态不能改变。在您的情况下,您没有更改对象new Integer(5),但您已更改引用i 以指向另一个对象。希望清楚:)
【讨论】:
i 是一个参考。您的代码将引用 i 更改为指向不同的、同样不可变的 Integer。
final Integer i = Integer.valueOf(5);
可能更有用。
【讨论】:
i = 6 起作用的原因是自动装箱正在拦截并将其转换为i = new Integer(6)。因此,正如@Peter 所说,您现在指向一个新对象。
【讨论】:
Integer.valueOf(6)。有关更多信息,请参阅此内容:marxsoftware.blogspot.com/2010/08/…
编译器自动装箱原始值,这意味着
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 返回的实例必须缓存一定范围。
【讨论】:
Integer 的不变性。 “....如果整数实例已被修改,它将打印 6!=6 代替。”好的,在知道可变对象AtomicInteger 上重复上述测试怎么样?它仍然会打印6!=5,在上面的论点上泼水。
i = new AtomicInteger(6);而不是i = 6;
will be compiled as... 这件事对我来说真的很有启发性。直到现在我才关心它实际上是如何工作的。太棒了
java 中的所有包装类都是不可变的。一旦创建了包装类对象,我们就无法更改其值,即无法更改包装在对象内部的值。因为包装类被用作原始数据类型的对象形式,并且如果它们是可变的,则在运行时会发生数据不一致。但是,您可以更改包装类引用变量以保存另一个对象。
【讨论】:
Integer i = new Integer(5);
i++; // i will become 6
其中i++ 与i = new Integer( i.intValue() + 1); 相同
【讨论】: