为什么整数在 Java 中是不可变的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22793616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are Integers immutable in Java?
提问by Mani
I know Integers are immutable in Java. But why it is designed this way?
我知道整数在 Java 中是不可变的。但是为什么要这样设计呢?
I went through other answers before asking this question:
在问这个问题之前,我浏览了其他答案:
i++ still working for immutable Integer in Java?
Why are Java wrapper classes immutable?
But I couldn't find the use case which mandates the Integer to be immutable. Are there any technical reasons like there are for String?
但是我找不到要求 Integer 不可变的用例。有没有像 String 那样的技术原因?
- String is used as parameter in network connection, database URLs etc. It could easily be compromised if it was mutable.
- To support StringPool facility.
- To support class loading mechanism in which Strings are used as arguments. String being mutable results in a wrong class being loaded.
- 字符串在网络连接、数据库 URL 等中用作参数。如果它是可变的,它很容易受到损害。
- 支持 StringPool 工具。
- 支持使用字符串作为参数的类加载机制。字符串可变会导致加载错误的类。
I understand there are wrappers like AtomicInteger
for mutable.
我知道有像AtomicInteger
可变的包装器。
UPDATE:
更新:
From the conversation, there is no universal reason that could mandate the Integers being immutable. However by doing immutable it provides some bonus as mentioned in the answers.
从谈话中,没有普遍的理由可以要求整数是不可变的。然而,通过做不可变,它提供了一些在答案中提到的奖励。
Such as this quote from Andrey
例如安德烈的这句话
possibility to cache.
Others are reducing global state
easier multithreading
缓存的可能性。
其他人正在减少全局状态
更简单的多线程
采纳答案by Durandal
You won't find a mandatory reason why java.lang
wrappers must be immutable. Simply because it's a design decision. They could have decided otherwise. The language designers had to choose between mutableand immutable. And they chose immutable. That's it.
您不会找到java.lang
包装器必须是immutable的强制性原因。仅仅因为这是一个设计决定。他们本可以做出其他决定。语言设计者不得不在mutable和immutable之间做出选择。他们选择了immutable。就是这样。
There are some compelling(IMO) reasons though to make them immutable:
有一些令人信服的(IMO)原因使它们不可变:
It's consistent with String
. The same reasoning you provided for String
to be immutableapplies to Integer
etc. as well (e.g. think of a port number in a property map). This generally applies to anymutable type.
它与String
. 您所提供的同样的道理String
是不变的适用于Integer
等,以及(如想在属性映射端口号)。这通常适用于任何可变类型。
Immutabletypes rule out a plethora of hard to find mistakes one can make where one involuntarily changed an objects member value by modifying the value obtained through a getter. It saves a lot of defensive copying when the type is immutable. The most infamous example is java.util.Date
, which is generally a pain to use because it's mutable(API issues aside).
不可变类型排除了大量难以发现的错误,人们通过修改通过getter获得的值不自觉地更改了对象成员值。当类型是不可变的时,它可以节省大量的防御性复制。最臭名昭著的例子是java.util.Date
,这通常很难使用,因为它是可变的(API 问题除外)。
Also immutable types allow for the use of shared instances, like e.g. Integer
does for commonly used values (see Integer.valueOf(int)
).
不可变类型也允许使用共享实例,就像Integer
常用的值一样(参见 参考资料Integer.valueOf(int)
)。
回答by Sotirios Delimanolis
Can the identity of the value 1
ever change? Can it become 2
? No. That's why Integer
and other numeric types are immutable. They're meant to model that identity.
价值的身份会1
改变吗?能变成2
吗?不。这就是为什么Integer
其他数字类型是不可变的。他们旨在塑造这种身份。
回答by supercat
In order for an object reference to encapsulate a value which is under the control of the thing that holds it, one of three conditions must apply:
为了使对象引用封装受持有它的事物控制的值,必须应用以下三个条件之一:
The class of the object must be immutable.
The reference must identify an instance that will never be exposed to anything that might mutate it.
The reference must never be shared with any object which isn't under the control of its holder, whether or not such a thing would mutate it.
对象的类必须是不可变的。
引用必须标识一个永远不会暴露给任何可能改变它的实例。
引用绝不能与任何不受其持有者控制的对象共享,无论这样的事情是否会改变它。
Code which holds references of type Integer
generally does so for the purpose of encapsulating integer values. Making Integer
immutable makes it possible for classes to freely share references that are used to encapsulate value. Although there are times when a MutableInteger
class would itself be useful [such a thing could probably be a little cleaner than a single-element int[]
and more efficient than an AtomicInteger
], one wouldn't pass a MutableInteger
class to a method as a means of passing the number therein; one would instead pass it for the purpose of giving that method a place to store a number.
保存类型引用的代码Integer
通常这样做是为了封装整数值。使Integer
不可变使类可以自由共享用于封装值的引用。尽管有时MutableInteger
类本身很有用 [这样的东西可能比单个元素int[]
更简洁,比一个更有效AtomicInteger
],但人们不会将MutableInteger
类传递给方法作为传递数字的一种方式其中;而是为了给该方法一个存储数字的地方而传递它。
回答by Sohail Si
An integer literal (2, 3) is also immutable e.g. int var=3;
It's the int
variable (var
on the left had side) that is mutable. The intention of Integer is "object as a value" (right hand side) rather than "object as a variable" (left hand side). Since Java uses references, variability can be either in reference or in the object contents. The object reference (variable r
in Integer r=2;
) can be the variable part. In result, variability is provided via a variable reference rather than would be using a constant reference (constant r
) and a variable content of the referred object. They could have used the class name Integer
as a variable but then another class name would have been necessary for immutable (right hand side value). So MutableInteger
and ImmutableInteger
are both used in programs at some points. However, people happen to use the latter more often. So, early on Java developers decided to use the shorter name Integer for the latter (ImmutableInteger
). There are various reasons why the latter turns out to be more useful that are explained in other answers to this post. Both are possible and they both exist, just there is more demand for the latter.
整数文字 (2, 3) 也是不可变的,例如 int var=3;
它是int
可变的变量(var
在左侧)。Integer 的意图是“对象作为值”(右侧)而不是“对象作为变量”(左侧)。由于 Java 使用引用,因此可变性可以存在于引用中,也可以存在于对象内容中。对象引用(变量r
in Integer r=2;
)可以是变量部分。结果,可变性是通过变量引用提供的,而不是使用常量引用 (constant r
) 和引用对象的变量内容。他们可以使用类名Integer
作为变量,但另一个类名对于不可变(右侧值)来说是必需的。所以MutableInteger
和ImmutableInteger
在某些时候都在程序中使用。然而,人们碰巧更频繁地使用后者。因此,Java 开发人员很早就决定使用较短的名称 Integer 来表示后者 ( ImmutableInteger
)。后者被证明更有用的原因有多种,在这篇文章的其他答案中进行了解释。两者都是可能的,它们都存在,只是对后者的需求更大。