考虑这段代码:

class test {
   public static void main(String[] args) {
      test inst_test = new test();
      int i1 = 2000;
      int i2 = 2000;
      int i3 = 2;
      int i4 = 2;
      Integer Ithree = new Integer(2); // 1
      Integer Ifour = new Integer(2); // 2
      System.out.println( Ithree == Ifour );
      inst_test.method( i3 , i4 );
      inst_test.method( i1 , i2 );
   }
   public void method( Integer i , Integer eye ) {
      System.out.println(i == eye );
   }
}

它打印:

false
true
false

我明白第一个 false, , == 运算符仅检查两个引用是否作用于同一个对象,在本例中则不然。

下列 truefalse 让我摸不着头脑。为什么Java会考虑 i3i4 平等但是 i1i2 不同的?两者都已包装为 Integer,不应该 两个都 评估为假?这种不一致有实际原因吗?

有帮助吗?

解决方案

将基元自动装箱为对象(如您的调用中所使用的那样) method 使用小值的缓存。来自 Java 语言规范第 5.1.7 节:

如果被装箱的值p是正确的,则为false,a字节,范围 u0000至 u007f的字符,或-128和127之间的int或int或短数字,然后让R1和R2为任何两个拳击转换的结果p。R1 == R2总是如此。

紧随其后的规范讨论部分也很有趣。值得注意的是 JVM 可以缓存 更多的 如果需要的话,你不能确定这样做的结果:

Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);

其他提示

自动装箱时,-128和127之间的整数被缓存,并返回相同的包装对象。以\ u0000的和\ u007F

之间布尔值和char值相同的

这是你得到的大部分时间,但是这取决于JVM实现。

这是因为拳击使得低于某个值(128,我认为)参考一些预先构造对象,整数和更高的值,以新的对象。

自动装箱用途的 Integer.valueOf(I)下,不新的整数(i)中,以构建Integer类的对象。

作为其他人说的valueOf()使用的高速缓存,多为空间效率。

不要在引用类型使用==,它几乎总是一个错误。

Integer类含有一些常用的实例的高速缓存中。值的范围通常从JVM变化到JVM(有时也是可配置的),但在一般的相关代码是这样的:

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

(来自太阳JDK 1.6代码)

这是像字符串实习,因为它既使用参考节省存储器和允许测试平等(例如<强> == 代替的等于

我猜想,包裹试图最小整数对象的数目和创建表示2太节省存储器只有一个对象。

只要记住永远不要使用==你永远不知道对象发生了什么。

自动装箱使用一些缓存机制。通常你应该永远依靠==,始终使用equals检查平等。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top