Глиф Учебники

Сравнение строк: == и equals

Справочник · Java · 1 минута чтения

Строки сравнивают методом equals:

Java
if (answer.equals("да")) {
    System.out.println("Согласие получено");
}

== у строк проверяет не текст, а то, один ли это объект в памяти. Две строки с одинаковым текстом могут быть разными объектами — тогда == вернёт false.

Почему == иногда «работает»

Java
public class Main {
    public static void main(String[] args) {
        String a = "Java";
        String b = "Java";
        String part = "Ja";
        String c = part + "va";
        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(a.equals(c));
        System.out.println("JAVA".equalsIgnoreCase(a));
    }
}
Вывод
true
false
true
true

Одинаковые строки, записанные прямо в коде в кавычках, Java хранит в одном экземпляре (в так называемом пуле строк). Поэтому a == b — true: это один объект. Строка c собрана во время работы программы — это новый объект, и a == c даёт false, хотя текст тот же. Строки из Scanner, из файла, из substring и replace — тоже новые объекты.

Отсюда коварство ==: в простом примере сравнение срабатывает, а в настоящей программе со вводом — нет. Не полагайтесь на него никогда.

Варианты сравнения

ЗадачаКак
Тот же текстa.equals(b)
Без учёта больших и маленьких буквa.equalsIgnoreCase(b)
Безопасно, если a может быть null"да".equals(a) или Objects.equals(a, b)
По алфавитуa.compareTo(b) — меньше нуля, ноль или больше нуля
Пустая ли строкаs.isEmpty() или s.isBlank() (пробелы тоже считаются пустотой)

a.equals(b) упадёт с NullPointerException, если a равно null. Поэтому известную строку ставят слева: "да".equals(answer). Objects.equals(a, b) (из java.util) работает, даже если null оба.

А как же switch

switch по строке сравнивает через equals сам, его можно использовать без опаски:

Java
switch (command) {
    case "start" -> System.out.println("Запуск");
    case "stop" -> System.out.println("Остановка");
    default -> System.out.println("Неизвестная команда");
}

Если command равна null, такой switch выбросит NullPointerException.

Подводные камни