優先順位の罠
このレッスンでできるようになることは、演算子の優先順位と短絡評価を踏まえて、複合した式の結果と例外の有無を予測できるようになることです。
まず予測してみます
次のコードは例外で落ちるでしょうか。
int b = 0;
if (b != 0 & 100 / b > 1) {
System.out.println("ok");
}落ちます。ArithmeticException です。&& に書き換えると落ちません。ここが試験の狙いどころです。
短絡評価とは
&& と || は短絡評価をします。左辺だけで答えが決まるなら、右辺を評価しません。&& の左辺が false なら右辺は見ませんし、|| の左辺が true なら右辺は見ません。
一方 & と | は、boolean どうしに使うと論理演算になりますが、必ず両辺を評価します。上の例では b != 0 が false でも 100 / b が実行され、ゼロ除算になります。
見た目が 1 文字違うだけで、右辺に副作用や例外があるときだけ挙動が変わるので、読み飛ばしやすい形です。
優先順位の順番
試験でよく問われる範囲を、強いほうから並べます。
- 後置
i++i-- - 前置
++i--i、単項!- - 乗除
*/% - 加減
+- - 比較
<><=>= - 等価
==!= &、^、|の順&&、次に||- 三項演算子
? : - 代入
=+=など
ここから、a + b * 2 は a + (b * 2) であり、(a + b) * 2 とは別物だと分かります。丸括弧を足すか外すかだけで答えが変わる問題が定番です。
代入は右から左
代入はいちばん弱く、しかも右結合です。x = y = 3 は x = (y = 3) と解釈され、両方が 3 になります。また複合代入には暗黙のキャストが入ります。
byte n = 10;
n += 300; // これはコンパイルできます
n = n + 300; // これはコンパイルできません+= は結果を左辺の型へ黙って詰め直すので、桁があふれても通ってしまいます。
演習
判定メソッドに 2 か所の間違いがあります。片方は短絡評価、もう片方は優先順位です。直してください。
要件
- b が 0 のときは例外を起こさず small を返すこと
- score は a に b の 2 倍を足した値にすること
- 戻り値は 札 と score を半角コロンでつないだ文字列にすること
入出力例
judge(10, 5) → "big:20"
judge(10, 0) → "small:10"
judge(50, 4) → "small:58"
judge(1, 3) → "big:7"ヒント
編集 LuaGate編集部