所有原始包装类都是不可变对象吗?

Java中的所有原始包装类都是不可变对象吗? 字符串是不可变的。 什么是其他不可变对象?

任何没有给你任何改变其中数据的方法的类型都是不可变的 – 就这么简单。 是的,所有原始包装类型都是不可变的1String 。 UUID , URL和URI是其他示例。

虽然内置Java API中的CalendarDate是可变的,但Joda Time中的许多类型都是不可变的 – 在我看来,这是Joda Time更易于使用的一个原因。 如果一个对象是不可变的,你可以在代码中的其他地方保留对它的引用,而不必担心其他一些代码是否会进行更改 – 这更容易推理你的代码。


1我的意思是java.lang.Integer等。如其他地方所述, Atomic*类是可变的,实际上必须是为了达到它们的目的。 在“标准的原始包装类集”和“包装原始值的类集”之间存在着不同的看法。

您可以非常轻松地编写自己的可变包装类:

 public class MutableInteger { private int value; public MutableInteger(int value) { this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } } 

正如你所看到的那样,包装类本身没有任何不可变性 – 只是标准的设计是不可变的,因为它没有提供任何改变包装值的方法。

请注意,对于常见值,这允许在装箱时重复使用相同的对象:

 Integer x = 100; Integer y = 100; // x and y are actually guaranteed to refer to the same object Integer a = 1000; Integer b = 1000; // a and b *could* refer to the same object, but probably won't 

在Java 5之前,所有原始包装类都是不可变的。

但是,Java 5中引入的primefaces包装类 ( AtomicIntegerAtomicLongAtomicBooleanAtomicReference )是可变的。

当然是。 包装类是不可变的。

你可以阅读为什么包装类在java中是不可变的? 了解包装类的不变性。

一个奇怪的“包装器”类是Void ,它没有任何有效的对象,不可变或其他。 它只能设置为null。

Void一个用途是标记没有值的generics返回类型。 (你不能使用原始类型或void

例如

 Callable callable = new Callable() { public Void call() { // do something return null; } }; 

即使Date在技​​术上是可变的,我也会将其描述为“通过对流不可变”。 通常理解或假设您不会更改Date对象,而是将其替换为与任何其他不可变对象一样更改它。