讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議3:三元操作符的類型務必一致 >

建議3:三元操作符的類型務必一致

三元操作符是if-else的簡化寫法,在項目中使用它的地方很多,也非常好用,但是好用又簡單的東西並不表示就可以隨便用,我們來看看下面這段代碼:


public class Client{

public static void main(Stringargs){

int i=80;

String s=String.valueOf(i<100?90:100);

String s1=String.valueOf(i<100?90:100.0);

System.out.println("兩者是否相等:"+s.equals(s1));

}

}


分析一下這段程序:i是80,那它當然小於100,兩者的返回值肯定都是90,再轉成String類型,其值也絕對相等,毋庸置疑的。嗯,分析得有點道理,但是變量s中三元操作符的第二個操作數是100,而s1的第二個操作數是100.0,難道沒有影響嗎?不可能有影響吧,三元操作符的條件都為真了,只返回第一個值嘛,與第二個值有一毛錢的關係嗎?貌似有道理。

果真如此嗎?我們通過結果來驗證一下,運行結果是:「兩者是否相等:false」,什麼?不相等,Why?

問題就出在了100和100.0這兩個數字上,在變量s中,三元操作符中的第一個操作數(90)和第二個操作數(100)都是int類型,類型相同,返回的結果也就是int類型的90,而變量s1的情況就有點不同了,第一個操作數是90(int類型),第二個操作數卻是100.0,而這是個浮點數,也就是說兩個操作數的類型不一致,可三元操作符必須要返回一個數據,而且類型要確定,不可能條件為真時返回int類型,條件為假時返回float類型,編譯器是不允許如此的,所以它就會進行類型轉換了,int型轉換為浮點數90.0,也就是說三元操作符的返回值是浮點數90.0,那這當然與整型的90不相等了。這裡可能有讀者疑惑了:為什麼是整型轉為浮點,而不是浮點轉為整型呢?這就涉及三元操作符類型的轉換規則:

若兩個操作數不可轉換,則不做轉換,返回值為Object類型。

若兩個操作數是明確類型的表達式(比如變量),則按照正常的二進制數字來轉換,int類型轉換為long類型,long類型轉換為float類型等。

若兩個操作數中有一個是數字S,另外一個是表達式,且其類型標示為T,那麼,若數字S在T的範圍內,則轉換為T類型;若S超出了T類型的範圍,則T轉換為S類型(可以參考「建議22」,會對該問題進行展開描述)。

若兩個操作數都是直接量數字(Literal)[1],則返回值類型為範圍較大者。

知道是什麼原因了,相應的解決辦法也就有了:保證三元操作符中的兩個操作數類型一致,即可減少可能錯誤的發生。

[1]"Literal"也譯作「字面量」。