所有的數學運算都認為是從左向右運算的,Java 語言中大部分運算符也是從左向右結合的,只有單目運算符、賦值運算符和三目運算符例外,其中,單目運算符、賦值運算符和三目運算符是從右向左結合的,也就是從右向左運算。
乘法和加法是兩個可結合的運算,也就是說,這兩個運算符左右兩邊的操作數可以互換位置而不會影響結果。運算符有不同的優先級,所謂優先級就是在表達式運算中的運算順序。
一般而言,單目運算符優先級較高,賦值運算符優先級較低。算術運算符優先級較高,關系和邏輯運算符優先級較低。多數運算符具有左結合性,單目運算符、三目運算符、賦值運算符具有右結合性。
Java 語言中運算符的優先級共分為 14 級,其中 1 級最高,14 級最低。在同一個表達式中運算符優先級高的先執行。表 1 列出了所有的運算符的優先級以及結合性。
表1 運算符的優先級
使用優先級為 1 的小括號可以改變其他運算符的優先級,即如果需要將具有較低優先級的運算符先運算,則可以使用小括號將該運算符和操作符括起來。例如下面的表達式:
在這個表達式中先進行括號內的減法運算,再將結果與 z 相乘,最后將積除以 5 得出結果。整個表達式的順序按照從左向右執行,比較容易理解。
再來看一個復雜的表達式,如下所示。
這個表達式中包含了算術運算符和邏輯運算符。根據表 1 中列出的優先級,可以確定它的執行順序如下:
1.先計算 y 的自減運算符,即 --y。
2.再計算 x 的自增運算符,即 ++x。
3.接着計算 z 的自增運算符,即 ++z。
4.由於邏輯與比邏輯或的優先級高,這里將2和3的結果進行邏輯與運算,即 ++x && ++z。
5.最后將4的結果與1進行邏輯或運算,即 --y||++x&&++z。
如果沒有上述對該表達式執行順序的說明,第一眼看到它時將很難識別優先級。對於這類問題,可以通過添加小括號使表達的順序更加清晰,而不用去查優先級表。如下所示為改進后的表達式。
技巧:記住這么多運算符的優先級是比較困難的,因此讀者應該在實際應用中多多練習。
因為 Java 運算符存在這種優先級的關系,因此在做 SCJP 的時候或者某些公司的面試題,有如下 Java 代碼:
問 c 的值是多少?這樣的語句實在太恐怖了,即使多年的老程序員看到這樣的語句也會眩暈。這樣的代碼只能在考試中出現,作為一個程序員如果寫這樣的代碼,恐怕他馬上就得走人了,因為他完全不懂程序開發。
源代碼就是一份文檔,源代碼的可讀性比代碼運行效率更重要。 因此在這里要提醒大家:
不要把一個表達式寫得過於復雜,如果一個表達式過於復雜,則把它分成幾步來完成。
不要過多地依賴運算符的優先級來控制表達式的執行順序,這樣可讀性太差,盡量使用()來控制表達式的執行順序。