为什么等于运算符的Integer值直到128数?

gok*_*ari 25 java integer equals-operator

为什么Integer "="运算符不适用于128和Integer值之后?有人可以解释这种情况吗?

这是我的Java环境:java版"1.6.0_37"

Java(TM)SE运行时环境(版本1.6.0_37-b06)

Java HotSpot(TM)64位服务器VM(内置20.12-b01,混合模式)

示例代码:

    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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

控制台输出的一部分:

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
Run Code Online (Sandbox Code Playgroud)

谢谢!

lba*_*scs 23

查看Integer的源代码.您可以在那里看到值的缓存.

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

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

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

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

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

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

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


Den*_*sca 6

根据Java语言规范:

如果被装箱值p是真,假字节,在范围\ u0000的一个char到\ u007f,或-128和127之间int或短号码,然后让r1和r2是任何两个装箱转换的结果p.始终是r1 == r2的情况.

JLS拳击转换

有关int缓存的更多信息,请参阅此文章

  • 这个答案是错的,它不得不对热点jvm做任何事情,缓存是在Integer的源代码中实现的, (5认同)
  • 这是不正确的.例如,为什么不查看`java.lang.Integer`的源代码. (3认同)

Duk*_*ing 6

Integer是一个包装类int.

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

如前所述,缓存了值-128到127,因此返回相同的对象.

如果超出该范围,将创建单独的对象,因此引用将不同.

要解决这个问题:

  • 制作类型int
  • 将类型转换为int
  • 使用 .equals()


归档时间:

查看次数:

17870 次

最近记录:

10 年,10 月 前