參考鏈接: Java條件表達式中的數字類型提升
Map<String, Integer> map = new HashMap<String, Integer>();? ?map.put("count", null);? ?Integer it = map == null ? 0 : map.get("count");? 注意:在第三行,會拋出java.lang.NullPointerException信息。因為分析:表達式二的類型為int,整個表達式類型為 Integer,JDK5.0會自動打包,所以表達式三 會獲得一個Integer,然后轉成int,再轉成Integer,如果是NULL在轉成int的時候拋出空指針異常。?
? 下面的程序將會打印出什么呢??
? public class DosEquis{? ? ?public static void main(String[] args){? ? ?char x = 'X';? ? ?int i = 0;? ? ?System.out.println(true ? x : 0);? ? ?System.out.println(false ? i : x);? ? ? }? ?}? ?這個程序由兩個變量聲明和兩個print語句構成。第一個print語句計算條件表達式(true ? x : 0)并打印出結果,這個結果是char類型變量x的值’X’。而第二個print語句計算表達式(false ? i : x)并打印出結果,這個結果還是依舊是’X’的x,因此這個程序應該打印XX。? ? ? 然而,如果你運行該程序,你就會發現它打印出來的是X88。這種行為看起來挺怪的。第一個print語句打印的是X,而第二個打印的卻是88。它們的不同行為說明了什么呢?? ? ? 答案就在規范有關條件表達式部分的一個陰暗的角落里。請注意在這兩個表達式中,每一個表達式的第二個和第三個操作數的類型都不相同:x是char類型的, 而0和i都是int類型的。混合類型的計算會引起混亂,而這一點比在條件表達式中比在其它任何地方都表現得更明顯。你可能考慮過,這個程序中兩個條件表達 式的結果類型是相同的,就像它們的操作數類型是相同的一樣,盡管操作數的順序顛倒了一下,但是實際情況并非如此。? ? ? 確定條件表達式結果類型的規則過于冗長和復雜,很難完全記住它們,但是其核心就是一下三點: 1、如果第二個和第三個操作數具有相同的類型,那么它就是條件表達式的類型。換句話說,你可以通過繞過混合類型的計算來避免×××煩。? 2、如果一個操作數的類型是T,T表示byte、short或char,而另一個操作數是一個int類型的常量表達式,它的值是可以用類型T表示的,那么條件表達式的類型就是T。? 3、否則,將對操作數類型運用二進制數字提升,而條件表達式的類型就是第二個和第三個操作數被提升之后的類型。? ? ? 2、3兩點是關鍵。在程序的兩個條件表達式中,一個操作數的類型是char,另一個的類型是int。在兩個表達式中,int操作數都是0,它可以被表示成 一個char。然而,只有第一個表達式中的int操作數是常量(0),而第二個表達式中的int操作數是變量(i)。因此,第2點被應用到了第一個表達式 上,它返回的類型是char,而第3點被應用到了第二個表達式上,其返回的類型是對int和char運用了二進制數字提升之后的類型,即int。? ? ? 條件表達式的類型將確定哪一個重載的print方法將被調用。對第一個表達式來說,print(char)將被調用,而對第二個表達式來 說,PrintStream.print(int)將被調用。前一個重載方法將變量x的值作為Unicode字符(X)來打印,而后一個重載方法將其作為 一個十進制整數(88)來打印。? ? ? 總之,通常最好是在條件表達式中使用類型相同的第二和第三操作數。否則,你和你的程序的讀者必須要徹底理解這些表達式行為的復雜規范。? ? ? 對 語言設計者來說,也許可以設計一個犧牲掉了部分靈活性,但是增加了簡潔性的條件操作符。例如,要求第二和第三操作數必須就有相同的類型,這看起來就很合 理。或者,條件操作符可以被定義為對常量沒有任何特殊處理。為了讓這些選擇對程序員來說更加容易接受,可以提供用來表示所有原始類型字面常量的語法。這也 許確實是一個好注意,因為它增加了語言的一致性和完備性,同時又減少了對轉型需求。
??
?
轉載于:https://blog.51cto.com/3470969/1126884