请考虑以下代码段:
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
!)
答案 0 :(得分:20)
是。 JLS §5.6.2指定二进制数字促销的规则。部分:
当运算符应用二进制时 数字促销到一对 操作数,每个都必须表示一个 可转换为数字的值 类型,以下规则适用于 订单,使用加宽转换 (§5.1.2)将操作数转换为 必要的:
如果任何操作数是a 引用类型,拆箱转换 (§5.1.8)被执行。
二进制数字提升适用于多个数字运算符,包括“数字相等运算符==和!=。”
JLS §15.21.1(数字等式运算符==和!=)指定:
如果操作数相等 运算符都是数字类型,或 一个是数字类型,另一个是数字类型 可转换(第5.1.8节)为数字 类型,二进制数字促销是 在操作数上执行(第5.6.2节)。
相反,JLS §15.21.3(参考等式运算符==和!=)提供:
如果操作数相等 运算符都是参考 键入或null类型,然后是 操作是对象相等
这符合拳击和拆箱的常识,只有在不匹配时才会这样做。
答案 1 :(得分:7)
我将首先解释, ==
是引用相等的时候,正好时它是数字相等。引用相等的条件更简单,因此首先解释它。
==
and !=
如果等于运算符的操作数都是引用类型或 null 类型,则操作是对象相等。
这解释了以下内容:
System.out.println(new Integer(0) == new Integer(0)); // "false"
两个操作数都是Integer
,它们是引用类型,这就是==
是引用相等比较的原因,而两个new
对象永远不会是==
,这就是它打印false
的原因。
要使==
为数字相等,至少有一个操作数必须是数字类型;具体如下:
==
and !=
如果等于运算符的操作数 的数值类型,或一个的数字类型,另一个可转换为数字类型,对操作数执行二进制数字提升。如果提升的操作数类型是
int
或long
,则执行整数相等测试;如果提升的类型是float or
double`,则执行浮点相等测试。请注意,二进制数字促销会执行值集转换和拆箱转换。
因此,请考虑以下事项:
System.out.println(new Integer(0) == 0); // "true"
这会打印true
,因为:
int
类型int
==
是数字相等操作==
和!=
的两个操作数都是引用类型,它将始终是引用相等操作
==
and !=
==
and !=