== と .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パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。