三元操作符是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"也譯作「字面量」。