为什么相等运算符适用于整数值直到128个数字?

2022-09-01 15:42:05

为什么 Integer 运算符不适用于 128 和整数值之后?有人能解释一下这种情况吗?==

这是我的 Java 环境:

java version "1.6.0_37"
Java(TM) SE Runtime Environment (build 1.6.0_37-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01, mixed mode)

示例代码:

Integer a;
Integer b;
a = 129;
b = 129;

for (int i = 0; i < 200; i++) {
    a = i;
    b = i;

    if (a != b) {
        System.out.println("Value:" + i + " - Different values");
    } else {
        System.out.println("Value:" + i + " - Same values");
    }
}

控制台输出的某些部分:

Value:124 - Same values
Value:125 - Same values
Value:126 - Same values
Value:127 - Same values
Value:128 - Different values
Value:129 - Different values
Value:130 - Different values
Value:131 - Different values
Value:132 - Different values

答案 1

查看整数 的源代码。您可以在此处查看值的缓存。

仅当使用 时才会发生缓存,而不是使用 .您使用的自动装箱使用 。Integer.valueOf(int)new Integer(int)Integer.valueOf

根据 JLS,您始终可以指望这样一个事实,即对于介于 -128 和 127 之间的值,在自动装箱后,您将获得相同的 Integer 对象,在某些实现中,即使对于更高的值,您也可能获得相同的对象。

实际上在Java 7中(我认为在Java 6的较新版本中),IntegerCache类的实现已经改变,并且上限不再是硬编码的,但它可以通过属性“java.lang.Integer.IntegerCache.high”进行配置,因此,如果您使用VM参数运行程序,则所有值都将获得“相同值”。-Djava.lang.Integer.IntegerCache.high=1000

但JLS仍然只保证它直到127:

理想情况下,对给定的基元值 p 进行装箱,将始终产生相同的引用。在实践中,使用现有的实现技术可能不可行。上述规则是务实的妥协。上面的最后一个子句要求始终将某些公共值装箱到无法区分的对象中。实现可能会懒惰或急切地缓存这些。

对于其他值,此公式不允许对程序员的盒装值的标识进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

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


答案 2

Integer是 的包装类。int

Integer != Integer比较实际的对象引用,其中将比较值。int != int

如前所述,将缓存值 -128 到 127,因此将为这些值返回相同的对象。

如果超出该范围,将创建单独的对象,以便引用将不同。

要修复它:

  • 使类型或int
  • 将类型转换为 或int
  • .equals()