Java入門のよくある間違い

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

はじめての Java プログラム

レッスンを読む

ダブルクォートとシングルクォートの混同

文字列は "Hello" のように 必ずダブルクォート で囲みます。'Hello' と書くと「文字 1 個」の型 (char) になってしまい、コンパイルエラーです

はじめての Java プログラムで詳しく読む

変数を宣言する

レッスンを読む

型を書き忘れる

age = 20; のように、いきなり代入から書くとエラーになります。Java では最初に必ず int age = 20; のように型を書く必要があります

変数を宣言するで詳しく読む

初期化せずに使う

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 です。「左から順番」と思い込んで計算するとズレます。迷ったらカッコを付けて自分の意図を明示しましょう

四則演算と剰余で詳しく読む

インクリメントとデクリメント

レッスンを読む

同じ式の中で同じ変数を何度も増減させる

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 を連結すると "null" になる

String name = null; String msg = "こんにちは、" + name; と書くと、msg は "こんにちは、null" という文字列になります。意図せず null を含んだ表示が出てしまい、ユーザーに気付かれて慌てる、というのは Java の現場でよくある失敗です。事前に if (name != null) でチェックするか、Objects.toString(name, "匿名") のようにデフォルト値を用意しましょう

文字列の連結で詳しく読む

型変換 (キャスト)

レッスンを読む

キャストの位置を間違える

(double)(a / b) のようにカッコ全体に掛けると、先に整数除算してから double 化することになり、小数部が消えます。(double) a / b のように 割り算する前のオペランド にキャストするのが正解です

型変換 (キャスト)で詳しく読む

桁あふれ (overflow)

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) を明示しないと、小数演算にはなりません

型変換 (キャスト)で詳しく読む