简短答案
关键是:
==
两个参考类型之间总是参考比较
- 通常,例如,使用
Integer
和String
,您可以equals
改用
==
引用类型和数字原始类型之间的始终是数字比较
- 引用类型将进行拆箱转换
- 拆箱
null
总是抛出NullPointerException
- 虽然Java对Java有很多特殊处理
String
,但实际上它不是原始类型
上面的语句适用于任何给定的有效Java代码。有了这种理解,您呈现的代码段中就不会存在任何不一致之处。
长答案
以下是相关的JLS部分:
如果相等运算符的操作数均为引用类型或null类型,则该操作为对象相等。
这解释了以下内容:
Integer i = null;
String str = null;
if (i == null) {
}
if (str == null) {
}
if (str == "0") {
}
两个操作数都是引用类型,这就是为什么==
引用相等比较。
这也解释了以下内容:
System.out.println(new Integer(0) == new Integer(0));
System.out.println("X" == "x".toUpperCase());
为了==
达到数值相等,至少一个操作数必须是数值类型:
如果相等运算符的操作数是两个数字类型的,或一个是数字类型的,并且另一种是可转换到数字类型,二进制数值提升时对操作数执行。如果操作数的提升类型为int
或long
,则执行整数相等性测试;否则,执行整数相等性测试。如果提升的类型为float or
double,则执行浮点相等性测试。
请注意,二进制数值升级执行值集转换和装箱转换。
这说明:
Integer i = null;
if (i == 0) {
}
这是来自有效Java 2nd Edition,第49项的摘录:首选原语而不是盒装原语:
总之,只要有选择,就优先于框式基元使用基元。基本类型更简单,更快速。如果必须使用盒装原语,请当心!自动装箱减少了使用装箱原语的冗长程度,但没有危险。当您的程序将两个装箱的原语与==
运算符进行比较时,它将进行身份比较,这几乎肯定不是您想要的。当您的程序进行涉及装箱和拆箱原语的混合类型计算时,它会进行拆箱,而当您的程序进行拆箱时,它可能会抛出NullPointerException
。最后,当您的程序将原始值装箱时,可能会导致创建昂贵且不必要的对象。
在某些地方您别无选择,只能使用盒装基元,例如泛型,但是否则您应该认真考虑使用盒装基元的决定是否合理。
参考文献
相关问题
相关问题