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

时间:2011-05-29 06:55:45

标签: java wrapper

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

4 个答案:

答案 0 :(得分:22)

任何没有给你任何改变其中数据的方法的类型都是不可变的 - 就这么简单。是的,所有原始包装类型都是不可变的 1 ,就像String一样。 UUIDURLURI是其他例子。

虽然内置Java API中的CalendarDate是可变的,但Joda Time中的许多类型都是不可变的 - 在我看来,这是 one < / em>为什么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

答案 1 :(得分:11)

在Java 5之前,所有primitive wrapper classes都是不可变的。

但是,Java 5(AtomicIntegerAtomicLongAtomicBooleanAtomicReference<V>)中引入的atomic wrapper classes是可变的。

答案 2 :(得分:3)

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

您可以阅读Why wrapper classes are immutable in java?以了解包装类的不变性。

答案 3 :(得分:0)

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

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

e.g。

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

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