6

我到处读到,当您在 Java 中定义一个介于 -128 到 127 之间的整数时,它不是创建一个新对象,而是返回一个已经创建的对象。

除了让新手程序员比较 Integer 对象以查看它们是否是相同的数字之外,我认为这样做没有任何意义==,但我认为这很糟糕,因为他们确信他们认为他们可以将任何 Integer 与 进行比较==,并且还在教学在任何编程语言中都是一个不好的做法:将两个“不同”对象的内容与==.

这样做的原因还有其他原因吗?或者在设计 JavaScript 中的可选分号之类的语言(在我看来)时,这只是一个错误的决定?

编辑:我在这里看到他们解释了行为:为什么整数常量池的行为在 127 处发生变化?

我在问他们为什么将其设计为具有这种行为,而不是为什么会发生这种行为。

4

2 回答 2

11

它被称为享元模式,用于最小化内存使用。

这些数字很可能会被重复使用,并且像这样的 autobox 类型Integer是不可变的(请注意,这不仅适用于Integer)。缓存它们使得它没有很多实例并且也减少了 GC(垃圾收集)的工作。

JLS 在5.1.7 中对此进行了介绍。拳击转换 专门说:

如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(含)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两个拳击转换。r1 == r2 总是如此。

理想情况下,对给定的原始值 p 进行装箱将始终产生相同的参考。在实践中,使用现有的实现技术这可能是不可行的。上述规则是一种务实的妥协。上面的最后一个条款要求某些常见的值总是被装箱到无法区分的对象中。实现可能会懒惰地或急切地缓存这些。对于其他值,此公式不允许程序员对装箱值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

这确保了在最常见的情况下,行为将是期望的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存所有 char 和 short 值,以及 -32K 到 +32K 范围内的 int 和 long 值。

于 2013-07-05T18:05:06.643 回答
2

我认为创建任何对象都比从符号表中获取对象要花费更多时间。此外,如果我没记错的话,堆上的每个对象都会为头部占用 24 个字节的额外空间。现在,如果程序员编写他/她的程序,大多数操作都是在小整数(在本例中为小整数)上完成的。因此,它可以节省大量空间并稍微提高性能。

于 2013-07-05T17:55:43.000 回答