繁体   English   中英

Java的==上的行为不一致

[英]Inconsistent behavior on java's ==

考虑以下代码:

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为true,false,一个字节,介于\\ u0000到\\ u007f之间的char或-128和127之间的int或short数字,则令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)而非新的Integer(i)来构造Integer类的对象。

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

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

我猜想包装会尽量减少Integer对象的数量,并只创建一个代表2个对象的对象,这也可以节省内存。

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

整数类包含一些常用实例的缓存。 值的范围通常因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的代码)

这就像字符串实习,因为它既节省了内存,又允许使用引用进行测试相等(例如==代替equals

自动装箱使用某些缓存机制。 通常,您永远不要依赖== ,始终使用equals来检查相等性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM