为什么整数在Java中是不可变的?

时间:2014-04-01 18:11:22

标签: java integer immutability

我知道整数在Java中是不可变的。但为什么这样设计呢?

在提出这个问题之前,我先回答了其他问题:

Is Integer Immutable

i++ still working for immutable Integer in Java?

Why are Java wrapper classes immutable?

但我无法找到强制整数为永久不变的用例。 是否存在类似String的技术原因?

  1. String用作网络连接,数据库URL等中的参数。如果它是可变的,很容易被破坏。
  2. 支持StringPool工具。
  3. 支持将字符串用作参数的类加载机制。字符串是可变的导致加载错误的类。
  4. 我知道像AtomicInteger这样的包装器是可变的。

    更新:

    从对话中,没有普遍的理由可以强制整数是不可变的。然而,通过做不变量,它提供了答案中提到的一些奖励。

    例如来自Andrey

    的引用
      

    缓存的可能性。

         

    其他人正在减少全球状态

         

    更容易多线程

5 个答案:

答案 0 :(得分:19)

您找不到java.lang包装器必须不可变的强制性原因。仅仅因为这是一个设计决策。他们本来可以做出决定。语言设计者必须在 mutable immutable 之间进行选择。他们选择了 immutable 。就是这样。

虽然有一些引人注目的(IMO)理由让它们不可变

String一致。您为String 不可变提供的相同推理也适用于Integer等(例如,考虑属性映射中的端口号)。 这通常适用于任何可变类型

不可变的类型排除了过多的难以发现的错误,可以通过修改通过 getter 获得的值来非自愿地更改对象成员值。 当类型不可变 时,它可以节省大量的防御性复制。最臭名昭着的例子是java.util.Date,这通常很难使用,因为它是可变的(除了API问题)。

同样不可变类型允许使用共享实例,例如Integer适用于常用值(请参阅Integer.valueOf(int))。

答案 1 :(得分:4)

1的标识是否会发生变化?可以成为2吗?不。这就是Integer和其他数字类型不可变的原因。他们的意图是塑造这种身份。

答案 2 :(得分:0)

为了使对象引用封装一个受持有它的东西控制的值,必须应用以下三个条件之一:

  1. 对象的类必须是不可变的。

  2. 引用必须标识一个永远不会暴露于任何可能使其变异的实例。

  3. 绝不能与任何不受其持有人控制的对象共享引用,无论这种对象是否会发生变异。

  4. 保存类型Integer的引用的代码通常是为了封装整数值。使Integer不可变使得类可以自由地共享用于封装值的引用。虽然有时MutableInteger类本身有用[这样的事情可能比单个元素int[]更清晰一些,并且效率高于AtomicInteger],但是#39; t将MutableInteger类传递给方法,作为传递数字的方法;为了给该方法一个存储数字的地方,我们会传递它。

答案 3 :(得分:0)

整数文字(2,3)也是不可变的,例如int var=3;这是int变量(左边的var有侧面)是可变的。 Integer的意图是“作为价值的对象”(右侧)而不是“作为变量的对象”(左侧)。由于Java使用引用,因此可变性可以在引用中或在对象内容中。对象引用(r中的变量Integer r=2;)可以是变量部分。结果,通过变量引用提供可变性,而不是使用常量引用(常量r)和引用对象的可变内容。他们可以使用类名Integer作为变量,但是对于不可变(右侧值),则需要另一个类名。因此MutableIntegerImmutableInteger在某些方面都用于程序中。然而,人们碰巧经常使用后者。因此,早期Java开发人员决定使用较短的名称Integer作为后者(ImmutableInteger)。有很多原因导致后者变得更有用,这在本文的其他答案中有所解释。两者都是可能的,它们都存在,只是对后者有更多的需求。

答案 4 :(得分:0)

我认为不变性是一种与垃圾收集机制相关的设计选择。至少,不变性有助于垃圾收集更有效地工作,因为消除了需要采取的几种开销机制来保证对象的完整性。

早期的编程语言是在硬件约束的限制非常明显的时代发明的(例如 RAM 和处理器速度以及没有运行时/裸机方法)。在这样的环境中,您需要非常小心地进行对象实例化,并且一旦实例化,您应该更新它而不是丢弃新值。在这方面,JAVA 是推广具有运行时和垃圾收集的新方法的先驱之一 - 这与不变性齐头并进。

请注意,最近使用 Python 等字节码的解释器(而不是 Perl)也使用整数和简单类型的不变性。

来自this source:

<块引用>

程序员通常不愿意使用不可变对象,因为他们担心创建新对象而不是更新对象的成本。对象创建的影响通常被高估,并且可以被与不可变对象相关的一些效率所抵消。其中包括因垃圾收集而减少的开销,以及消除保护可变对象免遭损坏所需的代码。