Java整数池。 为什么?

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

除了让新手程序员将Integer对象与==进行比较以查看它们是否是相同数字之外,我认为没有任何意义,但我认为这很糟糕,因为他们确定他们可以将任何整数与==进行比较,并且正在教授任何编程语言的不良实践:将两个“不同”对象的内容与==

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

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

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

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

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

JLS在5.1.7中介绍了这一点。 拳击转换特别说:

如果被装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或介于-128和127(含)之间的整数或短数,则让r1和r2为结果p的任何两个拳击转换。 始终是r1 == r2的情况。

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

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

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