3 回答

TA貢獻1826條經(jīng)驗 獲得超6個贊
簡短答案
關(guān)鍵是:
== 兩個參考類型之間總是參考比較
通常,例如,使用Integer和String,您可以equals改用
== 引用類型和數(shù)字原始類型之間的始終是數(shù)字比較
引用類型將進行拆箱轉(zhuǎn)換
拆箱null總是拋出NullPointerException
盡管Java對Java有很多特殊處理String,但實際上它不是原始類型
上面的語句適用于任何給定的有效 Java代碼。有了這種理解,您呈現(xiàn)的代碼段中就不會出現(xiàn)任何不一致之處。
長答案
以下是相關(guān)的JLS部分:
JLS 15.21.3參考相等運算符==和!=
如果相等運算符的操作數(shù)均為引用類型或null類型,則該操作為對象相等。
這解釋了以下內(nèi)容:
Integer i = null;
String str = null;
if (i == null) { // Nothing happens
}
if (str == null) { // Nothing happens
}
if (str == "0") { // Nothing happens
}
這兩個操作數(shù)都是引用類型,這就是為什么==引用相等比較。
這也解釋了以下內(nèi)容:
System.out.println(new Integer(0) == new Integer(0)); // "false"
System.out.println("X" == "x".toUpperCase()); // "false"
為了==達(dá)到數(shù)值相等,至少一個操作數(shù)必須是數(shù)值類型:
JLS 15.21.1數(shù)值相等算子==和!=
如果相等運算符的操作數(shù)是兩個數(shù)字類型的,或一個是數(shù)字類型的,并且另一種是可轉(zhuǎn)換到數(shù)字類型,二進制數(shù)值提升時對操作數(shù)執(zhí)行。如果操作數(shù)的提升類型為int或long,則執(zhí)行整數(shù)相等性測試;否則,執(zhí)行整數(shù)相等性測試。如果提升的類型為float ordouble`,則執(zhí)行浮點相等性測試。
請注意,二進制數(shù)值升級執(zhí)行值集轉(zhuǎn)換和裝箱轉(zhuǎn)換。
這說明:
Integer i = null;
if (i == 0) { //NullPointerException
}
這是摘自Effective Java 2nd Edition,第49條:首選基元而不是盒裝基元:
總之,只要有選擇,就優(yōu)先于框式基元使用基元?;绢愋透唵?,更快速。如果必須使用盒裝原語,請當(dāng)心!自動裝箱減少了使用裝箱原語的冗長程度,但沒有危險。當(dāng)您的程序?qū)蓚€裝箱的原語與==運算符進行比較時,它將進行身份比較,這幾乎肯定不是您想要的。當(dāng)您的程序進行涉及裝箱和拆箱原語的混合類型計算時,它會進行拆箱,而當(dāng)您的程序進行拆箱時,它可能會拋出NullPointerException。最后,當(dāng)您的程序?qū)⒃贾笛b箱時,可能會導(dǎo)致創(chuàng)建昂貴且不必要的對象。
在某些地方您別無選擇,只能使用盒裝基元,例如泛型,但是否則您應(yīng)該認(rèn)真考慮使用盒裝基元的決定是否合理。

TA貢獻1859條經(jīng)驗 獲得超6個贊
Java的開發(fā)者可以將==
運算符定義為直接對不同類型的操作數(shù)進行操作,在這種情況下,如果Integer I; int i;
進行比較,則I==i;
可能會問到“是否I
持有Integer
其值是i
?的引用”這一問題,可以很容易地得到回答。即使I
為null。不幸的是,Java不能直接檢查不同類型的操作數(shù)是否相等。而是檢查該語言是否允許將一個操作數(shù)的類型轉(zhuǎn)換為另一個操作數(shù)的類型,如果允許,則將轉(zhuǎn)換后的操作數(shù)與未轉(zhuǎn)換的操作數(shù)進行比較。這種行為意味著變量x
,y
以及z
與一些類型的組合,它可能有x==y
和y==z
,但x!=z
[例如,x = 16777216f y = 16777216 z = 16777217]。這也意味著將比較I==i
翻譯為“將I轉(zhuǎn)換為int
,如果沒有拋出異常,則將其與進行比較i
”。
添加回答
舉報