一尘不染

Java中奇怪的整数装箱

java

我刚刚看到类似于以下代码:

public class Scratch
{
    public static void main(String[] args)
    {
        Integer a = 1000, b = 1000;
        System.out.println(a == b);

        Integer c = 100, d = 100;
        System.out.println(c == d);
    }
}

运行后,此代码块将打印出来:

false
true

我理解为什么第一个是false:因为两个对象是单独的对象,所以==比较引用。但是我不知道为什么第二条语句返回了true?当Integer的值在一定范围内时,会出现一些奇怪的自动装箱规则吗?这里发生了什么?


阅读 298

收藏
2020-02-26

共1个答案

一尘不染

true行实际上是由语言规范保证的。从5.1.7节开始:

如果要装箱的值p为true,false,一个字节,\ u0000到\ u007f范围内的char或-128和127之间的int或short数字,则令r1和r2为任何两次装箱转换的结果的p。r1 == r2总是这样。

讨论继续进行,这表明尽管保证了第二行的输出,但第一行却没有保证(请参见下面引用的最后一段):

理想情况下,将给定的原始值p装箱将始终产生相同的参考。实际上,使用现有的实现技术可能不可行。以上规则是一种务实的妥协。上面的最后一个子句要求始终将某些通用值装在无法区分的对象中。该实现可以懒惰地或急切地缓存它们。

对于其他值,此公式不允许对程序员方面的带框值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

这样可以确保在最常见的情况下,这种行为将是理想的行为,而不会造成不必要的性能损失,尤其是在小型设备上。例如,较少内存限制的实现可能会缓存所有字符和短裤以及-32K-+ 32K范围内的整数和长整数。

2020-02-26