是否保证新的Integer(i)==我在Java?

考虑下面的代码片段:

int i = 99999999; byte b = 99; short s = 9999; Integer ii = Integer.valueOf(9); // should be within cache System.out.println(new Integer(i) == i); // "true" System.out.println(new Integer(b) == b); // "true" System.out.println(new Integer(s) == s); // "true" System.out.println(new Integer(ii) == ii); // "false" 

这很明显,为什么最后一行总是打印"false" :我们正在使用==引用标识比较,并且一个new对象将永远不会==到一个已经存在的对象。

问题是关于前3行:这些比较保证在原始int ,与Integer自动拆箱? 有没有原始的情况下将自动盒,而参考身份比较是执行? (这将是false !)

是。 JLS§5.6.2规定了二进制数字提升的规则。 部分:

当运算符将二进制数字提升应用于一对操作数时,每个操作数都必须表示一个可转换为数值types的值,应用以下规则,按照顺序使用扩展转换(第5.1.2节)根据需要转换操作数:

如果任何操作数是引用types,则执行拆箱转换(§5.1.8)。

二进制数字提升适用于多个数字运算符,包括“数字相等运算符==和!=”。

JLS§15.21.1 (数值相等运算符==和!=)指定:

如果等于运算符的操作数都是数字types的,或者一个是数字types,另一个是可转换的(§5.1.8)到数字types,则在操作数(§5.6.2)上执行二进制数字提升。

相比之下, JLS第15.21.3节 (参考平等操作符==和!=)提供了:

如果等于运算符的操作数既是引用types又是空types,则操作是对象相等的

这符合拳击和拆箱的共同理解,只有在不匹配时才会这样做。

我将首先解释什么时候 ==是一个引用的平等,而恰恰是一个数字的平等。 引用平等的条件比较简单,所以先说明。

JLS 15.21.3参考平等操作符==!=

如果等于运算符的操作数既是引用types又是types,则操作是对象相等的。

这解释了以下内容:

 System.out.println(new Integer(0) == new Integer(0)); // "false" 

两个操作数都是Integer ,它们是引用types,这就是为什么==是引用相等比较的原因,两个new对象永远不会互相== ,所以这就是为什么它打印为false

==为数字相等, 至less有一个操作数必须是数字types ; 这是指定如下:

JLS 15.21.1数值相等运算符==!=

如果等于运算符的操作数都是数字types,或者一个是数字types, 另一个是可以转换为数字types,则对操作数执行二进制数字提升。 如果提升types的操作数是intlong ,则执行整数相等性testing; 如果升级types是float or double,则执行浮点相等性testing。

请注意,二进制数字提升执行值集转换和拆箱转换。

因此,请考虑以下几点:

 System.out.println(new Integer(0) == 0); // "true" 

这打印true ,因为:

  • 右操作数一个数字的inttypes
  • 左操作数可以转换为数字types,通过拆箱为int
  • 因此==是一个数值相等的操作

概要

  • 如果==!=这两个操作数都是引用types,它将始终是引用相等操作
    • 操作数是否可以转换为数字types无关紧要
  • 如果至less有一个操作数是数字types,它将始终是一个数值相等操作
    • 自动取消装箱操作(最多!)将在必要时执行

参考

  • JLS 4.2。 原始types和值
    • 数字types是整型和浮点型。”
  • Java语言指南/自动装箱
  • JLS 5.1.8取消装箱转换
  • JLS 15.21.1数值相等运算符==!=
  • JLS 15.21.3参考平等操作符==!=
  • JLS 5.6.2二进制数字促销

相关问题

  • 在Java中比较两个Integers是否会发生自动拆箱?
  • 为什么这些==而不是equals()
  • Java:自动装箱和铸造有什么区别?