Ответ
Оператор == в Java сравнивает ссылки на объекты (т.е. адреса в памяти), а метод String.equals() сравнивает последовательность символов (содержимое) строк.
Ключевое различие:
==: Проверяет, указывают ли две переменные на один и тот же объект в памяти.equals(): Проверяет, имеют ли два разных объекта одинаковое содержимое.
Почему это важно? В Java строки могут быть представлены разными объектами даже с одинаковым текстом.
Пример, демонстрирующий проблему:
public class StringComparison {
public static void main(String[] args) {
// Строка-литерал попадает в пул строк (String Pool)
String literal1 = "hello";
String literal2 = "hello";
// Создание нового объекта String в куче (не в пуле)
String object1 = new String("hello");
String object2 = new String("hello");
// Сравнение через == (ссылки)
System.out.println("literal1 == literal2: " + (literal1 == literal2)); // true (один объект в пуле)
System.out.println("object1 == object2: " + (object1 == object2)); // false (два разных объекта)
System.out.println("literal1 == object1: " + (literal1 == object1)); // false (объект в пуле vs объект в куче)
// Сравнение через equals() (содержимое)
System.out.println("nliteral1.equals(literal2): " + literal1.equals(literal2)); // true
System.out.println("object1.equals(object2): " + object1.equals(object2)); // true
System.out.println("literal1.equals(object1): " + literal1.equals(object1)); // true
}
}
Вывод:
literal1 == literal2: true
object1 == object2: false
literal1 == object1: false
literal1.equals(literal2): true
object1.equals(object2): true
literal1.equals(object1): true
Практические рекомендации:
- Всегда используйте
equals()для сравнения строк по значению. - Для сравнения без учета регистра используйте
equalsIgnoreCase(). - Интернирование строк (
String.intern()) может перевести строку в пул, но это редко нужно и может иметь побочные эффекты на производительность. - Помните о проверке на null перед вызовом
equals(), чтобы избежатьNullPointerException. Безопасный паттерн:"expected".equals(variable) // Этот вызов безопасен, даже если variable == null // Или, если переменная может быть null: Objects.equals(str1, str2); // С Java 7Использование
==для строк — частая ошибка новичков, ведущая к трудноуловимым логическим багам.