{ } を省略してハマる
─ if (x > 0) return "positive"; のように { } なしで 1 行書いた後、「処理を追加しよう」と 2 行目を足しても、その 2 行目は if の中ではなく外として扱われます。インデントが揃っているのでぱっと見では気づきにくく、デバッグに時間を取られる典型例です
レッスンの本文で注意している点を、つまずきの側から29件ぶん並べ直しました。書いた覚えのある形が見つかったら、 そのままレッスンに戻って前後を読めます。
{ } を省略してハマる─ if (x > 0) return "positive"; のように { } なしで 1 行書いた後、「処理を追加しよう」と 2 行目を足しても、その 2 行目は if の中ではなく外として扱われます。インデントが揃っているのでぱっと見では気づきにくく、デバッグに時間を取られる典型例です
if (x = 0) と書いてしまう─ 代入の = と比較の == の混同です。x = 0 は「x に 0 を代入する」という意味で、条件式としては成り立ちません。Java では boolean を期待する場所に int の代入結果が来るのでコンパイルエラーになり、最近の言語の中では比較的安全です
if (x); と書いてしまう─ if のカッコの直後にセミコロン ; を置くミスです。これは「条件が true のとき何もしない」という空文として扱われ、その後ろの { } は if と無関係なただのブロックになります。文法エラーにならないのでとくに厄介で、コードレビューで指摘されるまで気づかないことすらあります
else の前にセミコロン ; を入れるif (n % 2 == 0) { ... }; のように } の後ろに ; を書いてしまうと、その時点で文が終わってしまい、続く else が孤立してエラーになります。} else { の前に余計な ; を入れない、これが鉄則です
else に条件を書いてしまう (else if との混同)else (n > 0) { ... } のように、else の後ろに丸カッコで条件を書こうとする間違いです。条件付きの else を書きたいときは else if (n > 0) { ... } のように else if と書きます。else 単体は条件を取らない、と覚えてください
% と == の優先順位の勘違いn % 2 == 0 という式は % のほうが == より先に計算される ので、内部的には (n % 2) == 0 と評価されます。心配ならカッコを付けて (n % 2) == 0 と書いてもまったく問題ありません。むしろ可読性が上がるので、慣れないうちはカッコを付けるのもおすすめです
先ほどの grade の例。score >= 60 を一番上に書くと、95 点でも C 判定になります。厳しい条件を上、ゆるい条件を下 が鉄則
else if を elseif と書くJava では else と if の 間に半角スペースが必要 です。elseif と続けて書くと ';' expected や 'else' without 'if' のようなコンパイルエラーになります。Python の elif とも違うので注意
else を忘れて return が足りないif と else if だけ書いて else を書かないと、戻り値のあるメソッドでは missing return statement のコンパイルエラーになります。最後は else でガッチリ閉じる、または if の外側で return を 1 本用意する
>= を > と書いてしまう「90 以上」のつもりで if (score > 90) と書くと、ちょうど 90 点が "A" ではなく "B" に落ちてしまいます。「以上」は >=、「より大きい」は >、と日本語と記号を必ずペアで覚えてください
if (score >= 60) ... else if (score >= 70) ... のように下から並べると、70 点以上の人もみんな最初の score >= 60 でヒットしてしまい、"D" のままになります。else if チェーンは必ず狭い (厳しい) 条件から書く
if (score >= 90) と else if (score >= 80 && score < 95) のように、範囲が重なる書き方をすると、どちらにヒットするかが順番に依存してしまい、読む人を混乱させます。境界はきっちり閉じる
else を忘れて漏れを作るelse if (score >= 60) で止めて else を書かないと、50 点のときに "F" を返す経路がなくなり、コンパイラに「missing return statement」と怒られます。多段階の if の最後は必ず else で受ける
% と == の優先順位を勘違いするyear % 4 == 0 を「year % (4 == 0)」と解釈してしまう人がいますが、実際は % のほうが == より優先順位が高いので (year % 4) == 0 と評価されます。心配なときは自分で () を付けて意図を明確にしてもよいです
&& と || の優先順位を取り違える&& は || より優先順位が高いです。a || b && c は a || (b && c) の意味になります。うるう年式で (year % 4 == 0 && year % 100 != 0) のように カッコで囲んでいる のはこの理由で、可読性とミス防止のためにカッコを残すのがおすすめです
== と = の打ち間違いyear % 4 == 0 を year % 4 = 0 と書くと「year % 4 に 0 を代入」しようとしてコンパイルエラーになります。比較は イコール 2 個、代入は イコール 1 個、と暗唱して指に覚えさせてください
break を忘れる一番多いミス。case 1: の処理後に break; を書かないと、case 2: のブロックに勝手に流れ込みます。return で抜ける形なら起きませんが、System.out.println(...) などで終わる場合は 必ず break; を最後に書くこと
case の値の型ミスマッチswitch (day) で day が int なのに case "1": と書くと、incompatible types: String cannot be converted to int というエラーが出ます。case の値は switch の式と 同じ型 にする必要があります
default を書き忘れる戻り値があるメソッドだと missing return statement のコンパイルエラーで気づけますが、void メソッドだと黙って通り抜けてバグの温床になります。default は常に書く習慣を付けましょう
switch 式 (Java 14+) との混同Java 14 から追加された switch 式 は String s = switch (day) { case 1 -> "Monday"; ... }; のように -> (アロー) を使う新構文です。従来の switch 文 (case ... : + break;) とは別物で、構文を混ぜると ';' expected などのエラーが出ます。このレッスンでは古典的な switch 文の方を使います
? と : の順番を逆にする正しいのは 条件 ? 真の値 : 偽の値 の順番です。条件 : 真の値 ? 偽の値 のように書くとコンパイルエラーになります。「クエスチョン (?) が先、コロン (:) が後」と覚えましょう
a ? b ? c : d : e ? f : g のような書き方は、構造を理解していてもパッと意味が取れません。3 段以上のネストは避けて if-else や switch を使う
? の後と : の後で型が違う (例: n >= 0 ? "正の数" : -n) と、Java は「結果の型がひとつに決まらない」と怒ります。文字列と数値を混ぜないように、両辺の型を必ず揃えましょう
勝ちパターンを 2 つしか書かずに残り 1 つを忘れる、引き分けの判定を書き忘れる、といったケースです。テストケースを増やしてあげると、こういった抜けが必ず炙り出されます。先ほどの Mermaid 図のように、すべての分岐を絵にしてから書くと抜けが減ります
|| と && の使い間違いme == 0 || opponent == 1 のように、本来 && で繋ぐべき条件を || で書いてしまうミスです。|| は どちらか片方でも true ならパスしてしまうので、「自分がグー」というだけで勝ち扱いになるなど、判定が壊滅的に狂います。「両方とも成り立つ必要があるなら &&、どれか 1 つでも成り立てばよいなら ||」と毎回声に出して確かめてください
勝ちパターンだけ書いて、勝ちでなかったらすべて "lose" を返してしまうと、janken(1, 1) のような同じ手のときも "lose" になります。me == opponent をどこかで必ず判定する必要があります
─ if (n % 3 == 0) return "Fizz"; から書き始めてしまうと、15 のときも "Fizz" が返ってしまい、"FizzBuzz" の出番がなくなります。FizzBuzz (両方の倍数) を 必ず最初に 判定するのが鉄則です
String.valueOf を忘れて型エラー─ 戻り値の型は String なのに、return n; と書いてしまうと「int を String として返せません」というコンパイルエラーになります。整数を文字列にしたいときは String.valueOf(n) か Integer.toString(n) を使うか、もしくは return "" + n; のように空文字と連結する手もあります
% 3 && % 5 のような略記を使う─ n % 3 && n % 5 のように書きたくなる人がいますが、これは文法エラーです。&& の左右には boolean が必要なので、必ず n % 3 == 0 && n % 5 == 0 のように == 0 まで 書いてください