Java: является ли assertEquals(String, String) надежным?
Я знаю, что ==
есть какие-то проблемы при сравнении двух Strings
. Кажется, что String.equals()
лучший подход. Ну, я делаю JUnit тестирование и моя склонность использовать assertEquals(str1, str2)
. Это надежный способ заявить две строки содержат одинаковое содержание? Я бы использовал assertTrue(str1.equals(str2))
, но тогда вы не получаете преимущества видеть, что ожидаемые и фактические значения при сбое.
на связанной заметке у кого-нибудь есть ссылка на страницу или поток, который ясно объясняет проблемы с str1 == str2
?
7 ответов
вы должны всегда использовать .equals()
сравнение Strings
в Java.
JUnit вызывает .equals()
метод для определения равенства в методе assertEquals(Object o1, Object o2)
.
Итак, вы определенно в безопасности, используя assertEquals(string1, string2)
. (Потому что String
С Object
s)
вот ссылка на большой вопрос Stackoverflow относительно некоторых различий между ==
и .equals()
.
assertEquals
использует equals
метод сравнения. Есть другое утверждение,assertSame
, который использует ==
оператора.
чтобы понять, почему ==
не следует использовать со строками, которые вам нужно понять, что ==
делает: он делает проверку личности. То есть, a == b
проверяет, если a
и b
относятся к тот же объект. Он встроен в язык, и его поведение не может быть изменено различными классами. The equals
метод, на с другой стороны, могут быть переопределены классами. В то время как его поведение по умолчанию (в Object
class) должен сделать проверку личности с помощью ==
оператора, многие классы, в том числе String
, переопределите его, чтобы вместо этого выполнить проверку "эквивалентности". В случае String
, вместо проверки, если a
и b
обратитесь к тому же объекту,a.equals(b)
проверяет, являются ли объекты, на которые они ссылаются, обеими строками, содержащими точно такие же символы.
аналогия время: представьте, что каждый String
объект-это лист бумаги с чем-то написанным на нем. Допустим, у меня есть два листка бумаги с надписью "фу" и еще один с надписью "бар". Если я возьму первые два листа бумаги и использую ==
чтобы сравнить их, он вернется false
потому что он по существу спрашивает: "Это тот же самый листок бумаги?". Ему даже не нужно смотреть на то, что написано на бумаге. Тот факт, что я даю ему два листа бумаги (а не один и тот же дважды), означает, что он будет возвращение false
. Если я использую , в equals
метод прочитает два листа бумаги и увидит, что они говорят одно и то же ("Foo"), и поэтому он вернется true
.
бит, который путается со строками, заключается в том, что Java имеет концепцию "интернирования" строк, и это (эффективно) автоматически выполняется на любых строковых литералах в вашем коде. Это означает, что если у вас есть два эквивалентных строковых литерала в коде (даже если они находятся в разных классах), они будут на самом деле оба относятся к одному и тому же
в двух словах-вы можете иметь два строковых объекта, которые содержат одни и те же символы, но являются разными объектами (в разных местах памяти). Оператор == проверяет, что две ссылки указывают на один и тот же объект (местоположение памяти), но метод equals() проверяет, совпадают ли символы.
обычно вам интересно проверить, содержат ли две строки одни и те же символы, а не указывают ли они на одно и то же место памяти.
Да, он используется все время для тестирования. Весьма вероятно, что используется платформа тестирования .equals () для подобных сравнений.
Ниже приведена ссылка, объясняющая "ошибку равенства строк". По сути, строки в Java являются объектами, и при сравнении равенства объектов обычно они сравниваются на основе адреса памяти, а не по содержанию. Из-за этого две строки не будут занимать один и тот же адрес, даже если их содержимое идентично, поэтому они не будут совпадать правильно, хотя при печати они выглядят одинаково.
http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/
public class StringEqualityTest extends TestCase {
public void testEquality() throws Exception {
String a = "abcde";
String b = new String(a);
assertTrue(a.equals(b));
assertFalse(a == b);
assertEquals(a, b);
}
}
От JUnit assertEquals(obj1, obj2)
действительно ли позвонить obj1.equals(obj2)
.
там же assertSame(obj1, obj2)
что значит obj1 == obj2
(т. е. проверяет, что obj1
и obj2
запускаем то же самое instance), чего вы пытаетесь избежать.
так что ты в порядке.
" The
==
оператор проверяет, если дваObjects
точно так жеObject
."
http://leepoint.net/notes-java/data/strings/12stringcomparison.html
String
- это Object
в java, поэтому он попадает в эту категорию правил сравнения.