java上的行为不一致==

and*_*and 8 java primitive integer

考虑以下代码:

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

它打印:

false
true
false
Run Code Online (Sandbox Code Playgroud)

我理解第一个false,==运算符只检查两个引用是否在同一个对象上工作,在这种情况下不是.

以下truefalse无我抓我的头.为什么Java的考虑i3i4平等的,但i1i2不同?两者都被包装到Integer,不应该评估为false?这种不一致是否有实际原因?

Jon*_*eet 15

将基元自动装箱到对象中(在调用中method使用的是使用小值的缓存.来自Java语言规范部分5.1.7:

如果被装箱的值p为true,false,一个字节,范围为\ u0000到\ u007f的char,或者介于-128和127之间的int或短号,则让r1和r2为任意两个装箱转换的结果p.始终是r1 == r2的情况.

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

Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);
Run Code Online (Sandbox Code Playgroud)

  • 故事的寓意应该是在比较对象时,equals()始终是正确的事情,即使对于原始类型的包装器也是如此. (4认同)

amo*_*fis 7

自动装箱时,缓存介于-128和127之间的整数,并返回相同的包装器对象.与\ u0000和\ u007F之间的布尔值和char值相同

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

  • 我曾经认为它也依赖于JVM,但它实际上是在规范中. (3认同)
  • (或者更确切地说,它是为这些值指定的,但不是为其他值指定的.) (2认同)