這個謎題將測試你對條件操作符的掌握程度,這個操作符有乙個更廣為人知的名字:問號冒號操作符。下面的程式將會列印出什麼呢?
public class dosequis
}
這個程式由兩個變數宣告和兩個print 語句構成。 第乙個 print 語句計算條件表示式(true ? x : 0)並列印出結果,這個結果是 char 型別變數x 的值'x』。而第二個 print 語句計算表示式(false ? i : x)並列印出結果,這個結果還是依舊是'x』的 x,因此這個程式應該列印 xx。然而,如果你執行該程式,你就會發現它列印出來的是 x88。這種行為看起來挺怪的。第乙個 print 語句列印的是x,而第二個列印的卻是 88。它們的不同行為說明了什麼呢?
答案就在規範有關條件表示式部分的乙個陰暗的角落裡。請注意在這兩個表示式中,每乙個表示式的第二個和第三個運算元的型別都不相同:x 是 char 型別的,而 0 和 i 都是 int 型別的。就像在謎題 5 的解答中提到的,混合型別的計算會引起混亂,而這一點比在條件表示式中比在其它任何地方都表現得更明顯。你可能考慮過,這個程式中兩個條件表示式的結果型別是相同的,就像它們的運算元型別是相同的一樣,儘管運算元的順序顛倒了一下,但是實際情況並非如此。 確定條件表示式結果型別的規則過於冗長和複雜,很難完全記住它們,但是其核心就是一下三點:
• 如果第二個和第三個運算元具有相同的型別,那麼它就是條件表示式的型別。換句話說,你可以通過繞過混合型別的計算來避免**煩。
• 如果乙個運算元的型別是 t,t 表示 byte、short 或 char,而另乙個運算元是乙個 int 型別的常量表示式,它的值是可以用型別 t 表示的,那麼條件表示式的型別就是 t。
• 否則,將對運算元型別運用二進位制數字提公升,而條件表示式的型別就是第二個和第三個運算元被提公升之後的型別。
2、3 兩點對本謎題是關鍵。在程式的兩個條件表示式中,乙個運算元的型別是char,另乙個的型別是 int。在兩個表示式中,int 運算元都是 0,它可以被表示成乙個 char。然而,只有第乙個表示式中的 int 運算元是常量(0),而第二個表示式中的 int 運算元是變數(i)。因此,第 2 點被應用到了第乙個表示式上,它返回的型別是 char,而第 3 點被應用到了第二個表示式上,其返回的型別是對 int 和 char 運用了二進位制數字提公升之後的型別,即 int。 條件表示式的型別將確定哪乙個過載的 print 方法將被呼叫。對第乙個表示式來說,printstream.print(char)將被呼叫,而對第二個表示式來說,printstream.print(int)將被呼叫。前乙個過載方法將變數 x 的值作為 unicode字元(x)來列印,而後乙個過載方法將其作為乙個十進位制整數(88)來列印。
至此,謎題被解開了。 總之,通常最好是在條件表示式中使用型別相同的第二和第三運算元。否則,你和你的程式的讀者必須要徹底理解這些表示式行為的複雜規範。
對語言設計者來說,也許可以設計乙個犧牲掉了部分靈活性,但是增加了簡潔性的條件操作符。例如,要求第二和第三運算元必須就有相同的型別,這看起來就很合理。或者,條件操作符可以被定義為對常量沒有任何特殊處理。為了讓這些選擇對程式設計師來說更加容易接受,可以提供用來表示所有原始型別字面常量的語法。這也許確實是乙個好注意,因為它增加了語言的一致性和完備性,同時又減少了對轉型的需求。
《java解惑》筆記八
要實現i i為true public static void main string args 控制台輸出 true 7ff8000000000000 7ff8000000000000double.nan表示乙個非數字 not a number 在記憶體儲存為0x7ff8000000000000,維...
Java解惑八 很多其它庫之謎
將執行緒的啟動方法start 寫成了run ps 管程 monitor 鎖有待進一步理解。執行緒中鎖的問題。理解不深刻。反射會造成訪問其它包中的非公共型別的成員。引起執行期異常。遮蔽 thread.sleep 方法遮蔽了自定的方法。反射 怎樣例項化非靜態內部類以及靜態內部類。system.out.w...
Elasticsearch系列之八 操作API
date 2019 04 07 思考了一下還是系統地將操作api總結一下,基本是參看官方文件,使用kibana執行命令 特別方便 我為了使用漢化kibana 不想執行python檔案 將es版本換成6.7.1,相應的ik外掛程式 kibana都換成了6.7.1版本 沒有用最新的7.0版本 建議首先安...