Как в Java работает сравнение строк с помощью оператора `==` и метода `equals()`?

«Как в Java работает сравнение строк с помощью оператора `==` и метода `equals()`?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Java сравнение строк имеет принципиально важную особенность из-за пула строк (String Pool) и различия между оператором == и методом equals().

  • == (оператор равенства): Сравнивает ссылки на объекты в памяти. Возвращает true, только если обе переменные указывают на один и тот же объект.
  • equals() (метод): Сравнивает содержимое (последовательность символов) строк. Это логическое сравнение.

Ключевое правило: Для сравнения содержимого строк всегда используйте equals() или equalsIgnoreCase().

Примеры, демонстрирующие разницу:

// Случай 1: Литералы (попадают в String Pool)
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2);      // true (один объект в пуле)
System.out.println(s1.equals(s2)); // true (содержимое одинаково)

// Случай 2: Явное создание объекта через `new`
String s3 = new String("Hello");
String s4 = new String("Hello");
System.out.println(s3 == s4);      // false (разные объекты в heap)
System.out.println(s3.equals(s4)); // true (содержимое одинаково)

// Случай 3: Смешанное сравнение
System.out.println(s1 == s3);      // false (объект из пула vs объект из heap)
System.out.println(s1.equals(s3)); // true (содержимое одинаково)

Почему так важно? Использование == для сравнения строк, полученных извне (от пользователя, из файла, сети), почти всегда даст неверный результат, так как это будут разные объекты.