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

为什么整数在Java中是不可变的?,java,integer,immutability,Java,Integer,Immutability,我知道整数在Java中是不可变的。但为什么它是这样设计的呢 在问这个问题之前,我仔细阅读了其他答案: 但我找不到要求整数不可变的用例。 是否有任何技术上的原因,比如字符串 字符串在网络连接、数据库URL等中用作参数。如果它是可变的,则很容易受到损害 支持StringPool设施 支持将字符串用作参数的类加载机制。字符串可变会导致加载错误的类 我知道有像AtomicInteger这样的包装器用于可变的 更新: 从对话中,没有一个普遍的理由可以规定整数是不可变的。然而,通过执行immutabl

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

在问这个问题之前,我仔细阅读了其他答案:

但我找不到要求整数不可变的用例。 是否有任何技术上的原因,比如字符串

  • 字符串在网络连接、数据库URL等中用作参数。如果它是可变的,则很容易受到损害
  • 支持StringPool设施
  • 支持将字符串用作参数的类加载机制。字符串可变会导致加载错误的类
  • 我知道有像
    AtomicInteger
    这样的包装器用于可变的

    更新:

    从对话中,没有一个普遍的理由可以规定整数是不可变的。然而,通过执行immutable,它提供了一些奖励,如答案中所述

    比如这段引用自

    缓存的可能性

    其他国家则在减少全球国家支出

    更简单的多线程


    1
    的标识是否会更改?它能变成
    2
    ?不。这就是为什么
    整数
    和其他数字类型是不可变的。它们是用来对身份进行建模的。

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

    但是,有一些令人信服的(IMO)理由使其不可更改:

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

    不可变类型排除了一个人可能犯的大量难以发现的错误,即通过修改通过getter获得的值而非自愿地更改了objects成员值当类型不可变时,它可以节省大量防御性复制。最臭名昭著的例子是
    java.util.Date
    ,使用它通常很痛苦,因为它是可变的(API问题除外)


    此外,不可变类型允许使用共享实例,例如,
    Integer
    对常用值(请参见
    Integer.valueOf(int)
    )所做的操作。

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

  • 对象的类必须是不可变的

  • 引用必须标识一个实例,该实例永远不会暴露于任何可能使其发生变异的事物

  • 引用绝不能与任何不受其持有者控制的对象共享,无论这样的事物是否会使其发生变异

  • 保存类型为Integer的引用的代码通常用于封装整数值。使
    Integer
    不可变使类可以自由共享用于封装值的引用。虽然有时
    MutableInteger
    类本身是有用的[这种东西可能比单个元素
    int[]
    更干净,而且比
    AtomicInteger
    ]更有效],但人们不会将
    MutableInteger
    类传递给方法作为传递其中数字的手段;相反,传递它是为了给该方法一个存储数字的位置。

    整数文本(2,3)也是不可变的,例如
    int var=3
    是可更改的
    int
    变量(
    var
    位于左侧)。整数的意图是“对象作为值”(右侧),而不是“对象作为变量”(左侧)。由于Java使用引用,可变性(mutability)既可以在引用中,也可以在对象内容中。对象引用(在
    整数r=2;
    中的变量
    r
    )可以是这种情况的变量方面。因此,可变性是通过“可变参考”而不是“可变基本类型内容的恒定参考(即无参考)”提供的。它将使用常量引用(常量
    r
    )和引用对象的可变内容


    他们可以将类名
    Integer
    设计为一个变量(非不可变),但最终另一个类名对于不可变(右侧值)是必需的。因此,
    MutableInteger
    ImmutableInteger
    都可以在程序中以某种形式使用。然而,人们更经常地使用后者。因此,早期Java开发人员决定对后者使用较短的名称Integer(
    ImmutableInteger
    )。后一种方法更有用、更不容易出错的原因有很多,这在本文的其他答案中得到了很好的解释。两者都是可能的,它们都存在,只是对后者有更多的需求。

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

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