Java 包装类真的不可变吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4117793/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Are Java wrapper classes really immutable?
提问by PetrosB
Java Wrapper classes are supposed to be immutable. This means that once an object is being created, e.g.,
Java Wrapper 类应该是不可变的。这意味着一旦创建了一个对象,例如,
Integer i = new Integer(5);
its value cannot be changed. However, doing
它的值不能改变。然而,做
i = 6;
is perfectly valid.
是完全有效的。
So, what does immutability in this context mean? Does this have to do with auto-boxing/unboxing? If so, is there any way to prevent the compiler from doing it?
那么,在这种情况下,不变性是什么意思?这与自动装箱/拆箱有关吗?如果是这样,有没有办法阻止编译器这样做?
Thank you
谢谢
回答by bmargulies
i
is a reference. Your code change the reference i
to point to a different, equally immutable, Integer
.
i
是参考。您的代码将引用更改i
为指向不同的、同样不可变的Integer
.
final Integer i = Integer.valueOf(5);
might be more useful.
可能更有用。
回答by Petar Minchev
Immutable means that the object state cannot be changed. In your case you haven't changed the object new Integer(5)
, but you have changed the reference i
to point to another object. Hope it is clear:)
不可变意味着对象状态不能改变。在您的情况下,您没有更改 object new Integer(5)
,但您已将引用更改i
为指向另一个对象。希望它很清楚:)
回答by josefx
The compiler autoboxes primitive values, this means that
编译器自动装箱原始值,这意味着
Integer value = 6;
will be compiled as
将被编译为
Integer value = Integer.valueOf(6);
Integer.valueOf will return an Integer instance with the given value. In your case i
will now reference the Integer(6) instead of the Integer(5), the Integer(5) object itself will not change.
Integer.valueOf 将返回一个具有给定值的 Integer 实例。在您的情况下,i
现在将引用 Integer(6) 而不是 Integer(5),Integer(5) 对象本身不会改变。
To see this you can do following
要看到这一点,您可以执行以下操作
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);
This will print 6!=5
, if the integer instance had been modified it would print 6!=6
instead.
这将打印6!=5
,如果整数实例已被修改,它将6!=6
改为打印。
To clarify this is only meant to show how an assignment to Integer only modifies the reference and does not alter the Integer instance itself. As user @KNU points out it does not prove or show the immutability of Integer, as far as I can tell the immutability is only indirectly given by the lack of modifying methods in its API and the requirement that instances returned by Integer.valueOf have to be cached for a certain range.
澄清这只是为了展示对 Integer 的赋值如何仅修改引用而不改变 Integer 实例本身。正如用户@KNU 指出的那样,它并没有证明或显示 Integer 的不变性,据我所知,不变性只是由于其 API 中缺少修改方法以及 Integer.valueOf 返回的实例的要求而间接给出的缓存在一定范围内。
回答by drekka
The reason i = 6
works is that auto-boxing is intercepting and turning it into i = new Integer(6)
. Thus as @Peter said, you are now pointing at a new object.
有效的原因i = 6
是自动装箱正在拦截并将其转换为i = new Integer(6)
. 因此,正如@Peter 所说,您现在指向一个新对象。
回答by Patchikori Rajeswari
All wrapper classes in java are immutable. We can't change the value of a wrapper class object once created, i.e., can't change the value wrapped inside the object. Because wrapper classes are used as object form of primitive data types and if they are mutable, data inconsistencies will occur in runtime. However, you can change the wrapper class reference variable to hold another object.
java中的所有包装类都是不可变的。包装类对象一旦创建就无法更改其值,即无法更改包装在对象内部的值。因为包装类是作为原始数据类型的对象形式使用的,如果它们是可变的,运行时就会出现数据不一致的情况。但是,您可以更改包装类引用变量以保存另一个对象。