Java中的所有原始包装类都是不可变对象吗?字符串是不可变的。什么是其他不可变对象?
答案 0 :(得分:22)
任何没有给你任何改变其中数据的方法的类型都是不可变的 - 就这么简单。是的,所有原始包装类型都是不可变的 1 ,就像String
一样。 UUID,URL和URI
是其他例子。
虽然内置Java API中的Calendar
和Date
是可变的,但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(AtomicInteger
,AtomicLong
,AtomicBoolean
和AtomicReference<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对象,但会替换它以像其他任何不可变对象一样更改它。