所有原始包装类都是不可变对象吗?
Posted
技术标签:
【中文标题】所有原始包装类都是不可变对象吗?【英文标题】:Are all primitive wrapper classes immutable objects? 【发布时间】:2011-09-04 05:06:23 【问题描述】:Java 中的字符串是不可变的。其他不可变对象是什么?
【问题讨论】:
Immutable Classes 的可能重复项 【参考方案1】:是的,当然。包装类是不可变的。
您可以阅读Why wrapper classes are immutable in java? 以了解包装类的不变性。
【讨论】:
【参考方案2】:一个奇怪的“包装”类是Void
,它没有任何有效的对象,不可变的或其他的。只能设置为null。
Void
的一个用途是标记没有值的通用返回类型。 (不能使用原始类型或void
)
例如
Callable<Void> callable = new Callable<Void>()
public Void call()
// do something
return null;
;
尽管Date
在技术上是可变的,但我仍将其描述为“通过约定不可变”。通常理解或假设您不会更改 Date 对象,而是会像任何其他不可变对象一样替换它以更改它。
【讨论】:
【参考方案3】:任何不给你任何方法来改变其中数据的类型都是不可变的——就这么简单。是的,所有原始包装器类型都是不可变的1,String
也是如此。 UUID、URL 和 URI
是其他示例。
虽然内置 Java API 中的 Calendar
和 Date
是可变的,但 Joda Time 中的许多类型是不可变的 - 在我看来,这就是 Joda 的一个原因时间更容易处理。如果一个对象是不可变的,您可以在代码中的其他地方保留对它的引用,而不必担心其他代码是否会进行更改 - reason 更容易你的代码。
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
【讨论】:
对乔达时间的看法。这也是它被认为是 JDK 中新时代 API 的基础的原因之一。 我知道这个帖子已经在 2 年前得到回答,但为了我的困惑,我需要知道。 @JonSkeet 你为什么说Integer a = 1000
和 Integer b = 1000
a 和 b 可以指同一个对象,但可能不是?而在Integer x = 100
和Integer y = 100
x 和 y 保证引用同一个对象?
@GrahamGriffiths:价值观确实如此。见docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7的最后几段
@gkns: 不是 some JVM...all 遵循语言规范的 JVM,值在 -128 到 +127(不是另一边)。但是,某些 JVM 可能会缓存 更多 个值。
Java 语言规范确实要求表示 -128 和 127 之间的整数值的 Integer
实例如果表示相同的整数值,则保证它们是相同的。见JLS § 5.1.7。【参考方案4】:
在 Java 5 之前,所有 primitive wrapper classes 都是不可变的。
但是,Java 5 中引入的 atomic wrapper classes(AtomicInteger
、AtomicLong
、AtomicBoolean
和 AtomicReference<V>
)是可变的。
【讨论】:
虽然我当然同意 AtomicInteger 等是可变的,但我不认为它们通常被称为“原始包装类”,因为它们与原始类型的关联并不那么紧密作为整数等......例如,他们不参与拳击。不过,提出它们很有用。 @Jon,说得好。我想它们有时被认为是原始包装器,因为AtomicInteger
和 AtomicLong
派生自 Number
,例如 Integer
和 Long
。
是的。我在回答中对此进行了更多讨论-希望您不介意我从您的回答中汲取灵感:)
@Jon,你的意思是,与我从你那里获得灵感的所有时间相反?请帮助自己:)以上是关于所有原始包装类都是不可变对象吗?的主要内容,如果未能解决你的问题,请参考以下文章