Java入門:繰り返しとメソッドのよくある間違い

レッスンの本文で注意している点を、つまずきの側から39件ぶん並べ直しました。書いた覚えのある形が見つかったら、 そのままレッスンに戻って前後を読めます。

for 文の基本

レッスンを読む

区切り文字をカンマにしてしまう

for (int i = 0, i < 10, i++) のようにカンマで区切るのは間違いで、正しくはセミコロン ; です

for 文の基本で詳しく読む

条件と更新を逆にして無限ループ

for (int i = 0; i < 10; i--) のように更新が逆向きだと i が永遠に増えないので、ループが終わりません。chotdekiru の Java Playground では 5 秒の実行制限で強制終了されますが、本番環境では CPU を食い続けてシステムが固まります

for 文の基本で詳しく読む

ループ変数をループの外で使ってしまう

for (int i = 0; i < 10; i++)i は丸カッコ内で宣言されているので、for ブロックの外では使えません

for 文の基本で詳しく読む

1 から N までの合計

レッスンを読む

sum を初期化せずに使う

int sum; とだけ書いて sum = sum + i; をやると、Java のコンパイラに「variable sum might not have been initialized」と怒られます。初期値 0 を必ず書きましょう

1 から N までの合計で詳しく読む

継続条件を i < n にしてしまう

i < n だと最後の n が足されません。sumOneToN(10) の答えが 55 ではなく 45 になります。<=< の違いで結果がガラッと変わるので、ループ条件を書いたら頭の中で「i は最後にいくつまで到達するか?」を必ず確認するクセをつけましょう

1 から N までの合計で詳しく読む

int の桁あふれ (overflow)

n がとても大きい (100000 以上など) と、合計が int の最大値 約 21 億 を超えて、マイナスの数になってしまうことがあります。今回の課題では n は小さいので気にしなくて OK ですが、本格的な数値計算では long 型を使うのが安全です

1 から N までの合計で詳しく読む

九九の段を作る

レッスンを読む

0 から始める / 1 から始めるの混同

九九は n * 1 から n * 9 までです。for (int i = 0; i < 9; i++) と書くと i は 0〜8 になり、n * 0 = 0 が先頭に入ってしまいます。今回は i = 1; i <= 9; i++ が正解です

九九の段を作るで詳しく読む

末尾の余計な空白

result = result + value + " "; のように書くと、最後の値の後ろにも空白が残ります。テストは "3 6 9 12 15 18 21 24 27" のように末尾に空白なしを期待しているので、if (i == 1) で分岐するか、if (i > 1) で先に空白を入れるパターンを使いましょう

九九の段を作るで詳しく読む

in の取り違え

文字列に並べるのは n * i の結果であって、i そのものではありません。うっかり result = result + i; と書くと "1 2 3 4 5 6 7 8 9" がいつも返ってきてしまい、n = 3 でも n = 7 でも同じ出力になります

九九の段を作るで詳しく読む

条件を更新し忘れて無限ループ

while (n > 0) { count = count + 1; } のように n を更新する行を書き忘れると、n は永遠に正のままで、count だけが増え続けます。Java の executor では 5 秒で強制終了されますが、本物のアプリでは画面が固まって最悪のユーザー体験になります。ループの中で「条件に関係する変数を必ず変える」のは絶対のルールです

while 文で詳しく読む

初期値を境界の外に置いてしまう

int count = 1; のように count を最初から 1 にしてしまうと、すべての結果が +1 ずれます。「ループに入る前に何回実行したことになっているか」をいつも意識して、初期値を決めましょう

while 文で詳しく読む

エッジケース (0 や負の数) を考えていない

今回は 01 桁として扱う仕様でしたが、これに気づかず while (n > 0) だけで提出すると、digitCount(0)0 を返してテスト失敗です。仕様の境界値は必ずテストケースに混ぜて、コードを書く前に紙に書き出すクセをつけましょう

while 文で詳しく読む

カウントダウン

レッスンを読む

終了条件の > 0>= 1 の混同

整数の n であればどちらも結果は同じですが、n > 0 と書くつもりで n >= 0 と書いてしまうと、0 までカウントが進んで "3 2 1 0" のように余計な 0 が混ざります。>= 1> 0 のどちらかで意図を統一しましょう

カウントダウンで詳しく読む

n-- の位置を間違えて無限ループ

result = result + n + " "; の 前 に n-- を書いてしまうと、最初の値 n が結果に入らないまま 1 減って、想定とずれた文字列になります。さらに n-- 自体を書き忘れると n が永遠に減らず無限ループです

カウントダウンで詳しく読む

末尾に余計な空白が残る

result + n + " " で連結すると、必ず最後にスペースが 1 つ余ります。"3 2 1 " のように末尾に空白が残った状態のままだと、テストの "3 2 1" と一致せず fail します。trim() で末尾の空白を必ず削ること

カウントダウンで詳しく読む

do { ... } while (条件) の末尾セミコロン忘れ

do { ... } while (n <= 0) で終わると「; expected」というコンパイルエラーになります。do-while は文の最後に 必ず ; を付けるのがルールです。while 文と違うところなので意識して書きましょう

do-while 文で詳しく読む

条件の方向を逆にする (上昇 vs 下降)

「正の数を見つける」課題なのに while (n > 0); と書いてしまうと、最初から正の数だったときに即終わり、負だったときは無限ループになります。「ループを 続ける ための条件」を書く、という基本に立ち戻ってください。n を上昇させて正を探すなら、ループ継続条件は n <= 0 (まだ正でない間続ける) です

do-while 文で詳しく読む

更新を忘れて無限ループ

do { ... } while (n <= 0); の中で n++ を書き忘れると、n がずっと初期値のままで条件が変わらず、永遠にループします。Java の Playground では実行が 5 秒で打ち切られますが、本番システムでこれをやると CPU 100% でサーバーが落ちます。ループ本体で必ず変数を更新する を呪文にしてください

do-while 文で詳しく読む

二重ループ

レッスンを読む

ij を混同する

内側で書きたいのに i++ と書いてしまうと、外側のカウンタを勝手にいじることになり、無限ループや想定外の動作になります。「外側 i、内側 j」と最初に決めてから書きましょう

二重ループで詳しく読む

内側ループ後の改行を忘れる

1 行ぶんの * を並べたあとに \n を追加しないと、全部が 1 行につながって *** のような出力になります。改行は内側ループの「外」、外側ループの「中」**が定位置です

二重ループで詳しく読む

末尾に余計な改行が付く

pyramid(3) の期待値は "*\n\n*" で、末尾の \n はありません。毎回改行を付けてしまうと最後にも 1 つ余分に付き、テストが fail します。if (i < n - 1) で最後の行だけ改行をスキップするか、改行を行の「先頭」に置いて 1 行目だけスキップするテクニックを使いましょう

二重ループで詳しく読む

break と continue

レッスンを読む

breakreturn を混同する

break はループから抜けるだけで、メソッド自体は終わりません。一方 return はメソッドそのものを終了します。「ループの外でまだ処理を続けたいなら break、メソッドごと終わらせたいなら return」と使い分けてください。「break を書いたのに return まで処理が来てしまった」と慌てる人が多いですが、それは break の正しい動きです

break と continueで詳しく読む

continue で更新を忘れて無限ループ

while ループの中で continue を使うとき要注意です。int i = 0; while (i < 10) { if (i == 3) continue; i++; } のように、continue の前にループ変数を更新していないと、i = 3 のところで永遠に止まります。for ループなら更新式が自動的に走るので比較的安全ですが、while のときは continue の前に必ず更新を済ませる、または continue の中でも更新する書き方を意識しましょう

break と continueで詳しく読む

ラベル付き break の構文ミス

ラベルは outer: のように : をつけて for の 直前の行に単独で 書きます。for outer:outer for のような書き方はコンパイルエラーです。break outer; の側はラベル名のあとに空白を入れて、最後に ; で締めます。たまにしか使わない構文なので、必要なときは公式ドキュメントで形を確認してください

break と continueで詳しく読む

FizzBuzz 完成

レッスンを読む

判定順序を逆にする

─ 前章でも触れた話ですが、if (i % 3 == 0) を最初に書いてしまうと 15 のときも "Fizz" が返ってしまい、"FizzBuzz" が一度も出てきません。必ず i % 15 == 0 を最初に判定する か、i % 3 == 0 && i % 5 == 0 を最初に書きましょう

FizzBuzz 完成で詳しく読む

末尾のスペースを取り忘れる

"1 2 Fizz 4 Buzz " のように末尾にスペースが残ると、テストの期待値 "1 2 Fizz 4 Buzz" と異なり fail します。trim() で取り除くか、最初から先頭判定方式で書きましょう

FizzBuzz 完成で詳しく読む

n0 のときに何が返るかを考えていない

─ もし fizzbuzzList(0) が呼ばれたら、for は 1 回も回らず result"" のまま trim() を経て空文字列が返ります。今回のテストでは n >= 1 しか使いませんが、業務コードなら エッジケース として「0 のときに何を返すべきか」を意識しておくとバグが減ります

FizzBuzz 完成で詳しく読む

メソッドを定義する

レッスンを読む

戻り値型を void にしているのに値を return してしまう

void は「戻り値なし」の意味なので、return "Hello"; のように値を返すとコンパイルエラーになります。値を返したいなら戻り値型を Stringint に変更しましょう

メソッドを定義するで詳しく読む

return; だけ書いて値を返し忘れる

逆に戻り値型を String にしているのに return; とだけ書くと「missing return value」エラーが出ます。戻り値の型に合った値を必ず指定してください

メソッドを定義するで詳しく読む

static の付け忘れ

chotdekiru の coding 問題は Solution.getGreeting() のように、クラス名から直接呼び出します。static を忘れるとインスタンス化が必要なメソッドになってしまい、テスト側から呼べずに fail します

メソッドを定義するで詳しく読む

引数を受け取るメソッド

レッスンを読む

引数の型を省略する

public static int square(n) のように int を書き忘れると、Java は「n の型がわからない」と怒ります。引数は 必ず型から書く、と覚えましょう。同じ理由で int a, b ではなく int a, int b のように毎回型を書きます

引数を受け取るメソッドで詳しく読む

引数の数を間違えて呼び出す

メソッド側が square(int n) のように 1 個の引数を期待しているのに、呼び出し側で Solution.square() (引数なし) や Solution.square(3, 4) (引数 2 個) と書くと、method square in class Solution cannot be applied to given types のようなエラーが出ます。引数の 個数と型 が完全に一致していないとコンパイルは通りません

引数を受け取るメソッドで詳しく読む

変数名が衝突すると思い込む

呼び出し側に int n = 5; という変数があると、「メソッド側の n と被るからダメなんじゃない?」と心配する人がいます。実際には別物として扱われるので、まったく問題ありません。むしろ呼び出し側でもメソッド側でも、その場で自然な名前を使うほうが読みやすいコードになります

引数を受け取るメソッドで詳しく読む

戻り値を返す

レッスンを読む

return 文を書かない

戻り値の型を Stringint と書いたのに、メソッド本体のどこにも return がないパターン。エディタのエラー欄に「missing return statement」と出たら、まず全ての分岐に return が届いているか確認しましょう。ifreturn して elsereturn しないと、それだけで未到達の分岐ができてしまいます

戻り値を返すで詳しく読む

return の後にコードを書く (dead code)

return 0; の次の行に System.out.println("...") のような処理を書いてしまうやつ。デバッグ用の println を消し忘れる事故が多いです。return の後に書いてあるコードは絶対に動きません

戻り値を返すで詳しく読む

戻り値型と return 値の型不一致

int を返すと書いたのに "123" のような String を返してしまうケース。逆に String を返すメソッドで return 0; と書いてしまうのもよくあります。エラー「incompatible types」「cannot return a value of type X」が目印

戻り値を返すで詳しく読む

複数の引数を取るメソッド

レッスンを読む

引数の順序を逆に渡す

rectangleArea(width, height) のつもりが rectangleArea(height, width) で呼んでしまうケース。長方形の面積では結果が同じなので気づきにくいですが、drawRect(x, y, width, height) のような関数では位置がズレて図形が変な場所に描かれます。呼び出すときは「メソッド宣言と同じ順番で書けているか」を必ず確認してください

複数の引数を取るメソッドで詳しく読む

型を 1 個だけ書く

int width, height のように書いて、int width, int height と書き忘れるパターン。Java のコンパイラから ';' expected <identifier> expected といった分かりにくいエラーが出ます。引数 1 個ごとに型を書く、を呪文として唱えてください

複数の引数を取るメソッドで詳しく読む

引数 0 個のメソッドと混同する

1 つ前のレッスンで書いた helloWorld() のような引数なしメソッドの感覚で、rectangleArea() と引数を渡さずに呼び出してしまうケース。コンパイラから method rectangleArea in class Solution cannot be applied to given types と長いエラーが出ます。引数を必要とするメソッドは、呼び出すときも同じ数だけ値を渡す必要があります

複数の引数を取るメソッドで詳しく読む