整数包装器对象仅在值 127 内共享相同的实例?

2022-09-01 02:36:37

这里它们是相同的实例:

Integer integer1 = 127;
Integer integer2 = 127;
System.out.println(integer1 == integer2);  // outputs "true"

但在这里它们是不同的实例:

Integer integer1 = 128;
Integer integer2 = 128;
System.out.println(integer1 == integer2);  // outputs "false"

为什么包装器对象仅在值 127 内共享同一实例?


答案 1

因为它是由 Java 语言规范指定的。

JLS 5.1.7 拳击转换

如果被装箱的值是 、 、 a 或 介于 到 的范围内,或者是介于 -128 和 127 之间的或 数字(含),则 let 和 是 的任意两个装箱转换的结果。总是这样。ptruefalsebytechar\u0000\u007fintshortr1r2pr1 == r2

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

这可确保在大多数情况下,行为将是所需的行为,而不会造成不适当的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存所有 charshort 值,以及 -32K 到 +32K 范围内的 intlong 值。


答案 2

java.lang.Integer 的来源:

public static Integer valueOf(int i) {
        final int offset = 128;
        if (i >= -128 && i <= 127) { // must cache
            return IntegerCache.cache[i + offset];
        }
        return new Integer(i);
    }

干杯!