java上的行为不一致==

时间:2009-07-18 22:52:05

标签: java integer primitive

考虑以下代码:

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,不应该两者评估为false?这种不一致是否有实际原因?

7 个答案:

答案 0 :(得分:15)

将基元自动装箱到对象中(在调用method时使用)会使用较小值的缓存。来自Java Language Specification section 5.1.7

  

如果装箱的值p为真,   false,一个字节,范围内的char   \ u0000到\ u007f,或者是int或short   在-128和127之间的数字,然后让   r1和r2是任意两个的结果   p的拳击转换它始终是   r1 == r2。

的情况

紧随其后的规范的讨论部分也很有趣。值得注意的是,JVM可以根据需要缓存更多值 - 您无法确定执行的结果:

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

答案 1 :(得分:7)

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

之间的布尔值和char值相同

这是大多数时候你得到的,但它取决于JVM的实现。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

Autoboxing使用 Integer.valueOf(i),而不是新的Integer(i)来构造Integer类的对象。

正如其他人所说,valueOf()使用缓存,主要是为了提高空间效率。

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

答案 4 :(得分:0)

我猜想包装会尝试最小化整数对象的数量,并且只创建一个表示2太多的内存对象。

请记住永远不要在对象上使用==你永远不知道会发生什么。

答案 5 :(得分:0)

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);
}

(来自sun JDK 1.6的代码)

这就像字符串实习一样,因为它既可以节省内存,又可以使用引用允许测试相等(例如 == 代替等于

答案 6 :(得分:0)

Autoboxing使用一些缓存机制。通常,您不应该依赖==,始终使用equals来检查相等性。