В КУРСЕ?

Разбираемся в теме

Строки одинаковые, а Java отвечает false: что именно сравнивает знак равенства

Две строки выглядят одинаково, но проверка через два знака равенства возвращает false. Для начинающего это похоже на случайность языка. На самом деле сравниваются разные свойства: являются ли ссылки указателями на один объект и совпадает ли последовательность символов. Если разделить эти вопросы, результат становится предсказуемым и его проще объяснить на собеседовании.

Переменная и объект не одно и то же

Представим два отдельных объекта String, каждый из которых содержит слово Север. Переменная a ссылается на первый объект, переменная b — на второй. Содержимое совпадает, но объекты различны. Для ссылочных значений оператор == проверяет, указывают ли они на один объект, либо являются ли обе ссылки null. Поэтому в нашем примере сравнение a == b даёт false. Это не сообщение о различии букв, а ответ на вопрос об идентичности объектов.

Метод equals у String сравнивает содержимое

Для проверки одинаковой последовательности символов у строк используют equals. В рассматриваемом примере a.equals(b) даст true, поскольку оба объекта содержат одинаковые символы. Теперь добавим переменную c, которой присвоена ссылка a. Новый строковый объект от такого присваивания не появляется: a и c указывают на один и тот же. Поэтому a == c будет true, а содержимое также совпадёт. Бумажная схема со стрелками помогает увидеть различие между копированием ссылки и созданием второго объекта.

Удачный пример не меняет смысл оператора

В некоторых случаях одинаковые строковые литералы могут ссылаться на общий объект. Тогда сравнение через == тоже вернёт true. Это не делает оператор проверкой текста и не позволяет применять его вместо equals к произвольным входным строкам. Полезный вопрос звучит так: какое свойство нужно проверить по условию задачи? Если важны символы, решение должно выражать именно это намерение, а не зависеть от того, как конкретные строки появились в памяти.

Отсутствующее значение требует отдельного внимания

Если a равно null, вызов a.equals(b) не может обратиться к объекту и приведёт к NullPointerException. Для сравнения с учётом возможного null можно использовать Objects.equals. При двух null он возвращает true; при одном null и одной обычной строке — false; в остальных подходящих случаях использует equals. Но технически корректное сравнение не решает вопрос смысла данных. Приложению всё равно нужно определить, допустимо ли отсутствие строки и что оно означает: неизвестное значение, ошибку ввода или другой предусмотренный случай.

Попробуйте на практике

Нарисуйте объекты и ссылки, чтобы предсказать результаты сравнения без догадок.

  1. Изобразите два отдельных прямоугольника String с одинаковым словом Север. Проведите стрелку a к первому, b ко второму.
  2. Добавьте стрелку c к тому же прямоугольнику, что и a. Подпишите, что c хранит скопированную ссылку, а не новый объект.
  3. Запишите результаты a == b, a.equals(b) и a == c. Для каждого укажите, сравниваются ссылки или содержимое.
  4. Отдельно рассмотрите два отсутствующих значения и сравнение через Objects.equals. Затем замените одно из них обычной строкой и предскажите новый результат.
  5. Сформулируйте правило выбора проверки для задачи сравнить введённые названия. Укажите, как обрабатывается null, вместо предположения, что его никогда не будет.

Как проверить результат. Для трёх основных проверок получены false, true и true. Вы объясняете ответы через объекты и символы, а случай null рассматриваете отдельно.

Частые вопросы

Если == иногда работает для одинакового текста, зачем менять проверку?

Совпадение результата в частном случае не меняет назначение оператора. Для произвольных строк сравнение содержимого должно быть выражено явно.

Любой метод equals сравнивает объекты по их полям?

Нет. Поведение зависит от класса и его реализации. В этой статье рассматривается String, у которого equals проверяет последовательность символов.

Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.

Зарегистрируйтесь, чтобы уточнить возможность доступа к этому материалу

Зарегистрироваться
← К списку материалов