Я знаю, что ==
есть некоторые проблемы при сравнении двух Strings
. Кажется, String.equals()
это лучший подход. Ну, я делаю тестирование JUnit, и я склонен использовать assertEquals(str1, str2)
. Это надежный способ утверждать, что две строки содержат одинаковое содержимое? Я бы использовал assertTrue(str1.equals(str2))
, но тогда вы не получите преимущества от просмотра ожидаемых и фактических значений при сбое.
На связанной заметке, есть ли у кого-нибудь ссылка на страницу или ветку, которая явно объясняет проблемы str1 == str2
?
Ответы:
Вы должны всегда использовать
.equals()
при сравненииStrings
в Java.JUnit вызывает
.equals()
метод для определения равенства в методеassertEquals(Object o1, Object o2)
.Таким образом, вы, безусловно, безопасно использовать
assertEquals(string1, string2)
. (Потому чтоString
s естьObject
s)Вот ссылка на отличный вопрос о Stackoverflow, касающийся некоторых различий между
==
и.equals()
.источник
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
чаще, чем можно было ожидать.источник
В двух словах - у вас может быть два объекта String, которые содержат одинаковые символы, но являются разными объектами (в разных местах памяти). Оператор == проверяет, что две ссылки указывают на один и тот же объект (область памяти), но метод equals () проверяет, совпадают ли символы.
Обычно вас интересует проверка, содержат ли две строки одинаковые символы, а не указывают ли они на одну и ту же ячейку памяти.
источник
источник
Да, он все время используется для тестирования. Весьма вероятно, что среда тестирования использует .equals () для таких сравнений.
Ниже приведена ссылка, объясняющая «ошибку равенства строк». По сути, строки в Java являются объектами, и когда вы сравниваете равенство объектов, обычно они сравниваются по адресу памяти, а не по содержимому. Из-за этого две строки не будут занимать один и тот же адрес, даже если их содержимое идентично, поэтому они не будут соответствовать друг другу, даже если при печати они выглядят одинаково.
http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/
источник
JUnit
assertEquals(obj1, obj2)
действительно звонитobj1.equals(obj2)
.Есть также то,
assertSame(obj1, obj2)
что делаетobj1 == obj2
(то есть, проверяет этоobj1
иobj2
ссылается на тот же экземпляр), чего вы пытаетесь избежать.Так что ты в порядке.
источник
http://leepoint.net/notes-java/data/strings/12stringcomparison.html
String
находитсяObject
в Java, поэтому он попадает в эту категорию правил сравнения.источник