文末の ; を忘れる
Java は return "Hello, Java!"; のように、文の終わりに必ずセミコロンが要ります。これを忘れるとコンパイラに怒られます
レッスンの本文で注意している点を、つまずきの側から28件ぶん並べ直しました。書いた覚えのある形が見つかったら、 そのままレッスンに戻って前後を読めます。
; を忘れるJava は return "Hello, Java!"; のように、文の終わりに必ずセミコロンが要ります。これを忘れるとコンパイラに怒られます
文字列は "Hello" のように 必ずダブルクォート で囲みます。'Hello' と書くと「文字 1 個」の型 (char) になってしまい、コンパイルエラーです
return を忘れる戻り値の型を String と書いたのに return を書かないと「missing return statement」と怒られます。戻り値があるメソッドは必ず return で締めましょう
age = 20; のように、いきなり代入から書くとエラーになります。Java では最初に必ず int age = 20; のように型を書く必要があります
int 1stScore = 100; はコンパイルエラー。int firstScore = 100; のように英字始まりにします
int x; System.out.println(x); のように、値を入れる前にローカル変数を使うと variable x might not have been initialized と怒られます
int age = "20"; のように、int 型の箱に文字列を入れようとするとエラーになります。int age = 20; のように、型と値の種類を合わせましょう
int avg = (a + b) / 2; と書いて、平均が想定より 1 小さい、というのは定番の罠です。double avg = (a + b) / 2.0; のように、片方を小数にして回避しましょう
int x = 10 / 0; を実行すると ArithmeticException: / by zero が出てプログラムが落ちます。% も同様で 10 % 0 も例外になります。割る前に if (b != 0) でチェックするか、b == 0 の場合の戻り値を決めておくのが安全です
1 + 2 * 3 は 9 ではなく 7 です。「左から順番」と思い込んで計算するとズレます。迷ったらカッコを付けて自分の意図を明示しましょう
b = a++; と b = ++a; を「同じだろう」と思って書くと、b に入る値が違ってバグになります。代入や式の中で使うときは、必ずどちらか意識すること
int y = x++ + x++; のように 1 行で x を 2 回動かすコードは、読みづらいうえに動作の理解も難しくなります。Java では仕様上動作は決まっていますが、避けるべきコード の代表例です
n をそのまま n++ してしまう今回の課題のように引数の値を保ったまま +1 -1 した値が欲しい場合、n++ をすると n の値そのものが変わってしまいます。必ず別の変数にコピーしてから動かすこと
= と == の混同上で説明した通り。if (a = 5) と書いてしまうと Java ではコンパイルエラー、他の言語では「代入してから true 判定」という別の動きになる罠です
== で比較するString s1 = "hello"; String s2 = new String("hello"); s1 == s2 は意外にも false になります。文字列の中身を比べたいときは必ず s1.equals(s2) を使ってください。== はオブジェクトの「参照」が同じかを見るので、中身が同じでも別オブジェクトなら false です
== 比較double x = 0.1 + 0.2; x == 0.3 は false です。double は内部で 2 進数表現するため、計算誤差が生じます。浮動小数を比べたいときは Math.abs(x - 0.3) < 1e-9 のように「許容誤差以内か」で判定するのが定石です
& | (ビット演算) と && || の混同& 1 個と | 1 個は、int 用のビット演算子です。boolean にも一応使えますが、短絡評価が効かないので推奨されません。if の条件には必ず && || を 2 個重ねて書きましょう
! を忘れる / 付け忘れる「ログインしていない場合」は !isLoggedIn です。isLoggedIn のままだと逆の意味になります。日本語の「~でない」を ! に翻訳する習慣をつけてください
&& は || よりも優先順位が高いです。a || b && c は a || (b && c) の意味になります。意図したとおりに書きたいときは、迷わずカッコ () で囲みましょう
a + b * c を (a + b) * c と勘違いする数学の 2 + 3 × 4 と同じく、* が先です。Java の式を読むときは、まず * / % を探して心の中で先にカッコを補うクセを付けましょう
x = y = z の結合方向を逆にする代入 = は 右から左 に結合するので x = (y = z) と読みます。(x = y) = z ではないので注意。さらに代入式は = の右辺の値を返すため、if ((line = reader.readLine()) != null) のような書き方も存在します
& | と論理演算 && || の優先順位を混同するビット演算 & ^ | は等価演算子 == != や関係演算子 < > よりも優先順位が低く、論理演算子 && || よりは高い位置にあります。ただし & と && の本質的な違いは優先順位だけでなく 短絡評価 (short-circuit evaluation) の有無です。&& は左辺が false の時点で右辺を評価しませんが、& は必ず両辺を評価します。たとえば if (obj != null & obj.getValue() > 0) のように & を使うと、obj が null でも右辺が実行されて NullPointerException が発生します。論理判定では必ず && || を使ってください
"合計: " + a + b と書くと、a + b が最初に連結されてしまい、a = 1, b = 2 の場合 "合計: 12" になります。"合計: " + (a + b) のようにカッコで括れば "合計: 3" になります
1 + 2 + "円" は "3円" ですが、"金額: " + 1 + 2 は "金額: 12" です。String が登場した瞬間から、以降の + は文字列連結になります
"null" になるString name = null; String msg = "こんにちは、" + name; と書くと、msg は "こんにちは、null" という文字列になります。意図せず null を含んだ表示が出てしまい、ユーザーに気付かれて慌てる、というのは Java の現場でよくある失敗です。事前に if (name != null) でチェックするか、Objects.toString(name, "匿名") のようにデフォルト値を用意しましょう
(double)(a / b) のようにカッコ全体に掛けると、先に整数除算してから double 化することになり、小数部が消えます。(double) a / b のように 割り算する前のオペランド にキャストするのが正解です
long → int や int → byte のような縮小変換で、変換先の範囲を超えると値が壊れます。たとえば int n = (int) 3000000000L; は int の上限 (約 21 億) を超えるため、まったく違う負の数になります。(int) のキャストはコンパイラに「失われてもいいから変換する」と伝える宣言なので、警告は出ません。範囲を超えていないか自分でチェックする責任があります
(double) を片側だけに付けるのを忘れるint a = 7, b = 2; のとき、double r = a / b; と書いても結果は 3.0 で、3.5 にはなりません。整数除算してから double に拡大しているだけだからです。少なくともどちらか一方に (double) を明示しないと、小数演算にはなりません