Code Fix

中級

== と .equals() の違い(文字列比較)

Java初学者が最も多く踏む罠。参照比較と値比較の違い、定数プール、null安全な書き方まで扱います。

なぜエラーが出ないのか

出力: false
(エラーなし)
javacは何も報告しません。文法として正しいためです
出力: false
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  public class Main {
 2      public static void main(String[] args) {
 3          String a = new String("java");
 4          String b = new String("java");
 5          System.out.println(a == b      );
                                     ^
 6      }
 7  }
出力: false期待: true (コンパイルは通っています)

== は参照が同じかを見ます。newで作った2つのStringは中身が同じでも別のオブジェクトです。

直し方: == b.equals(b) にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  import java.util.Scanner;
 2  
 3  public class Main {
 4      public static void main(String[] args) {
 5          Scanner sc = new Scanner(System.in);
 6          String cmd = sc.nextLine();
 7          if (cmd == "quit"     ) {
                          ^
 8              System.out.println("quit");
 9          }
10      }
11  }
出力: (何も出ない)期待: quit (コンパイルは通っています)

入力から作られたStringは定数プールを使いません。== では絶対に一致しない典型パターンです。

直し方: == "quit".equals("quit") にします。

この問題を解いてみる →

パターン3

 1  public class Main {
 2      public static void main(String[] args) {
 3          String s = null;
 4          System.out.println(s.equals("a")   );
                                       ^
 5      }
 6  }
Exception in thread "main" java.lang.NullPointerExceptionexited with code 1

nullに対してメソッドは呼べません。定数を左に置くとnull安全に比較できます。

直し方: s.equals("a")"a".equals(s) にします。

この問題を解いてみる →

よくある誤解

== でたまたま動くことがあります。リテラル同士は定数プールで同じ実体になるためです。「動いたから正しい」が最も危険なパターンです。

まとめ

== と .equals() の違い(文字列比較)は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)