謎題8: dos equis
這個謎題將測試你對條件操作符(冒號問號操作符)的掌握程式,看下面的程式會列印出什麼結果?
public class dosequis
}只要對條件操作符了解的都知道第一條列印語句應該列印的是字元x,第二條列印語句也應該列印出字元x,即列印結果應當是xx。而執行後,實際列印出來的卻是x88,那這是什麼原因導致的呢?
之前在謎題5中,我們討論過混合型別的計算會引起混亂,而看上面程式的兩個條件表示式中,每個條件表示式的第二和第三個運算元都分別是char型別和int型別以及int型別和char型別,是不同的型別,所以我們可以看出,混合型別計算引起的混亂,在條件表示式中表現的比其他任何地方都更明顯。但你可能會說,既然兩個表示式的第二第三個運算元都是char型別和int型別(僅僅是顛倒了順序而已),並且兩個表示式的結果型別也是相同的,那為什麼第一條列印語句列印出來的結果是正確的呢?其實不然,儘管運算元的順序顛倒了,但是實際情況並非我們想象中的那麼簡單。我們先來看下確定條件表示式結果型別的三點核心規則:
1.如果第二個和第三個運算元具有相同的型別,那麼它就是條件表示式的型別。換句話說,可以通過繞過混合型別的計算來避免**煩;
2.如果乙個運算元的型別是t,t表示byte、short或char,而另外乙個運算元是乙個int型別的常量表示式,它的值可以用型別t表示,那麼條件表示式的型別就是t;
3.否則,將對運算元型別進行二進位制數字提公升,而條件表示式的型別就是第二個和第三個運算元被提公升之後的型別。
對於本謎題而言,第二條和第三條規則是關鍵。很清楚的能看出,第一條列印語句中的第三個運算元是乙個int型別的常量表示式,並且能用char型別表示,符合第二條規則,所以列印出來的條件表示式的型別為char,即列印出字元x。而第二條列印語句中的第二個運算元i是int型別的變數,那麼就會執行第三條規則,列印出來的條件表示式的型別是對int和char進行二進位制數字提公升之後的型別,即int型別數值88。條件表示式的型別將確定呼叫哪乙個過載的print方法。對第乙個表示式來說,將呼叫printstream.print(char),而對第二個表示式來說,將呼叫printstream.print(int)。前乙個過載方法將變數x的值作為unicode字元(x)列印,而後乙個過載方法將其作為乙個十進位制整數(88)列印。那麼,我們應該怎樣才能使程式列印出我們想要的結果呢?我們只需要將final修飾符用於i的宣告,可以把i轉變為乙個常量表示式,從而讓程式列印出xx,但是這仍舊會引起混亂。為了消滅這種混亂,最好的方法就是將i的型別從int更改為char。
總之,通常最好是在條件表示式中使用型別相同的第二和第三運算元。否則,你和你程式的閱讀者必須徹底理解這些表示式行為的複雜規範。
Java解惑之字元謎題(2)
11 字元相加 system.out.println h a system.out.println h a 上面兩行 列印出來的結果是不同的,第一行的結果是ha,第二行的結果是169。這個很明顯吧,h 和 a 都是char型別的字面常量,char型別不能相加,會自動轉換為int型別進行計算。如果需要...
Java8之Lambda表示式
intstream.range 1000,10000 filter v v 1000 v 1000 v 1000 v 100 v 100 v 100 v 10 v 10 v 10 v foreach system.out println 上面的表示式中多處用到lamnda表示式以及stream ap...
JavaScript 正規表示式解惑
正規表示式手冊 我們來舉個例子 電子郵箱 example qq.com 1.username example a z0 9 2.3.公司名 qq.com da z a z 4.匹配開始位置!5.匹配結束位置!6.a za z 代表範圍 7.代表長度 最後,我們對應正則手冊,乙個個對應,就會出現以下正...