Bỏ qua để đến nội dung

So sánh chuỗi với equals và toán tử ==

== trên đối tượng (bao gồm String) so sánh tham chiếu (địa chỉ trong bộ nhớ), không so sánh nội dung. Điều này thường gây bất ngờ vì String “trông giống” kiểu nguyên thủy:

String a = "hello";
String b = "hello";
System.out.println(a == b); // true - NHƯNG chỉ vì cả hai literal trùng nhau trong string pool!
String c = new String("hello");
System.out.println(a == c); // false - c là một đối tượng MỚI, khác tham chiếu với a!
System.out.println(a.equals(c)); // true - equals() so sánh đúng NỘI DUNG

Kết quả của == trên String literal có thể tình cờ đúng nhờ cơ chế string pool (Java tái sử dụng các literal giống nhau), khiến lập trình viên lầm tưởng == luôn hoạt động đúng cho String - cho đến khi gặp chuỗi được tạo bằng new String(...), đọc từ file, hoặc ghép từ nhiều phần (những trường hợp không dùng string pool), thì == bất ngờ trả về false dù nội dung giống hệt:

String input = new Scanner(System.in).nextLine(); // giả sử người dùng nhập "yes"
if (input == "yes") { // BẪY! Gần như luôn false, dù input thực sự là "yes"
System.out.println("Đồng ý");
}

Luôn dùng .equals() (hoặc .equalsIgnoreCase()) để so sánh nội dung chuỗi, không bao giờ dùng ==:

String input = new Scanner(System.in).nextLine();
if (input.equals("yes")) { // ĐÚNG cách
System.out.println("Đồng ý");
}

⚠️ Nếu input có thể là null, gọi input.equals("yes") sẽ ném NullPointerException. Cách an toàn hơn: đặt literal (chắc chắn không null) làm bên gọi equals():

if ("yes".equals(input)) { // an toàn kể cả khi input là null -> trả về false, không ném lỗi
System.out.println("Đồng ý");
}

Nguyên tắc tương tự áp dụng cho mọi kiểu đối tượng khác (Integer, các class tự định nghĩa,…) - == luôn so sánh tham chiếu trừ khi là kiểu nguyên thủy.

== trên String so sánh tham chiếu, không so sánh nội dung - kết quả có thể “tình cờ đúng” nhờ string pool, gây hiểu nhầm.

  • Luôn dùng .equals()/.equalsIgnoreCase() để so sánh nội dung chuỗi
  • Đặt literal ở bên trái lời gọi equals() ("yes".equals(x)) để tránh NullPointerException khi biến có thể là null