为什么等于操作适用于整数值,直到128号? [重复](Why equal operator wo

2019-07-20 09:18发布

这个问题已经在这里有一个答案:

  • 为什么在Java中比较整数包装时128 == 128假的,但127 == 127是真的吗? 6个回答

为什么整数“=”操作不为128的整数值后工作? 有人可以解释这种情况呢?

这是我的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");
        }
    }

控制台输出的某些部分:

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

谢谢!

Answer 1:

退房整数的源代码 。 你可以看到有值的缓存。

如果你使用的缓存只发生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。



Answer 2:

Integer是一个包装类int

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

如前所述,值-128到127缓存,所以相同的对象是那些返回。

如果超出该范围,单独的对象将被创建,因此参考值将是不同的。

要解决这个问题:

  • 使类型int
  • 铸造类型来int
  • 使用.equals()


Answer 3:

根据Java语言规范:

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

JLS装箱转换

请参阅这篇文章,INT缓存的更多信息



Answer 4:

在整数对象具有一个内部高速缓存机制:

private static class IntegerCache {
    static final int high;
    static final Integer cache[];

    static {
        final int low = -128;

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }

    private IntegerCache() {}
}

另见的valueOf方法:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

这就是为什么你应该使用valueOf ,而不是new Integer 。 自动装箱使用此高速缓存。

也看到这个帖子: https://effective-java.com/2010/01/java-performance-tuning-with-maximizing-integer-valueofint/

使用==是不是一个好主意,使用等于比较值。



Answer 5:

使用.equals()而不是==

整型值仅缓存号-127和128之间,因为他们是最常用。

if (a.equals(b)) { ... }


Answer 6:

这取决于你如何让你的Integer的情况下,它可能没有任何价值的工作:

System.out.println(new Integer(1) == new Integer(1));

版画

false

这是因为==操作符应用于引用类型的操作数无关,与操作数代表的价值。



Answer 7:

这是因为Integer类的实现逻辑。 它已准备为对象,直到128可以签号码http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Integer.java开源-jdk例如(搜索缓存[])。
不应使用比拟的基本对象==可言,但有一个例外,以枚举。



文章来源: Why equal operator works for Integer value until 128 number? [duplicate]