为什么 Java 包装类是不可变的?

我知道适用于一般不可变类的常见原因,即

  1. 不能改变作为副作用
  2. 易于推理他们的状态
  3. 固有的线程安全
  4. 无需提供克隆/复制构造函数/工厂复制方法
  5. 实例缓存
  6. 无需防御性副本。

但是,包装类表示基元类型,而基元类型是可变的。那么为什么包装类不可变呢?


答案 1

但是,包装类表示基元类型,而基元类型(字符串除外)是可变的。

首先,String 不是基元类型。

其次,谈论基元类型是可变的没有意义的。如果像这样更改变量的值:

int x = 5;
x = 6;

这不会改变数字 5 - 而是会改变 的值。x

虽然包装器类型可以变得可变,但在我看来,这样做会很烦人。我经常使用这些类型的只读集合,并且不希望它们是可更改的。偶尔我想要一个可变的等价物,但在这种情况下,很容易想出一个,或者使用这些类。Atomic*

我发现自己希望这样,并且不可变的次数远远超过我发现自己想要可变的次数......(当然,我通常会选择Joda Time,但Joda Time的好处之一是不可变性。DateCalendarInteger


答案 2

对于某些类型,还有可变的线程安全包装器。

AtomicBoolean
AtomicInteger
AtomicIntegerArray
AtomicLong
AtomicLongArray
AtomicReference - can wrap a String.
AtomicReferenceArray

加上一些异国情调的包装纸

AtomicMarkableReference - A reference and boolean
AtomicStampedReference - A reference and int