assertEqualsиспользует equalsметод для сравнения. Существует другое утверждение assertSame, которое использует ==оператор.
Чтобы понять, почему ==не следует использовать со строками, вам нужно понять, что ==делает: он проверяет идентичность. То есть a == bпроверяет, есть ли aи bссылаются ли на один и тот же объект . Он встроен в язык, и его поведение не может быть изменено различными классами. equalsМетод, с другой стороны, могут быть перекрыты классами. Хотя его поведение по умолчанию (в Objectклассе) заключается в проверке идентичности с использованием ==оператора, многие классы, в том числе String, переопределяют его, чтобы вместо этого выполнить проверку "эквивалентности". В случае String, вместо проверки, если aи bссылаются на тот же объект,a.equals(b) проверяет, являются ли объекты, на которые они ссылаются, строками, которые содержат одинаковые символы.
Время аналогии: представьте, что каждый Stringпредмет - это лист бумаги с чем-то написанным на нем. Допустим, у меня есть два листа бумаги с надписью «Foo» и еще один с надписью «Bar». Если я возьму первые два листа бумаги и использую их ==для сравнения, он вернется, falseпотому что по сути спрашивает «это один и тот же лист бумаги?». Не нужно даже смотреть на то, что написано на бумаге. Тот факт, что я даю ему два листа бумаги (а не один и тот же дважды), означает, что он вернется false. Если я использую equals, однако, equalsметод прочитает две бумажки и увидит, что они говорят одно и то же («Foo»), и поэтому он вернется true.
Проблема, которая путает со строками, заключается в том, что в Java есть концепция «интернирования» строк, и это (эффективно) автоматически выполняется для любых строковых литералов в вашем коде. Это означает, что если в вашем коде есть два эквивалентных строковых литерала (даже если они находятся в разных классах), они на самом деле оба ссылаются на один и тот же Stringобъект. Это заставляет ==оператора возвращаться trueчаще, чем можно было ожидать.