是否保证新的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的操作数是
int
或long
,则执行整数相等性testing; 如果升级types是float or
double,则执行浮点相等性testing。请注意,二进制数字提升执行值集转换和拆箱转换。
因此,请考虑以下几点:
System.out.println(new Integer(0) == 0); // "true"
这打印true
,因为:
- 右操作数是一个数字的
int
types - 左操作数可以转换为数字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:自动装箱和铸造有什么区别?