Вопрос

Я знаю, что у == есть некоторые проблемы при сравнении двух строк . Кажется, что String.equals () - лучший подход. Ну, я провожу тестирование JUnit, и я склонен использовать assertEquals (str1, str2) . Это надежный способ утверждать, что две строки содержат одинаковое содержимое? Я бы использовал assertTrue (str1.equals (str2)) , но тогда у вас не будет возможности увидеть ожидаемые и фактические значения при сбое.

В связанной заметке есть ли у кого-нибудь ссылка на страницу или поток, в котором четко объясняются проблемы с str1 == str2 ?

Это было полезно?

Решение

Вы должны всегда использовать .equals () при сравнении Strings в Java.

JUnit вызывает метод .equals () для определения равенства в методе assertEquals (объект o1, объект o2) .

Итак, вы определенно в безопасности, используя assertEquals (string1, string2) . (Поскольку String являются Object s)

Вот ссылка на замечательный вопрос Stackoverflow относительно некоторых различий между == и .equals () .

Другие советы

assertEquals использует метод равно для сравнения. Существует другое утверждение assertSame , в котором используется оператор == .

Чтобы понять, почему == не следует использовать со строками, необходимо понять, что делает == : он проверяет идентичность. То есть a == b проверяет, ссылаются ли a и b на один и тот же объект . Он встроен в язык, и его поведение не может быть изменено различными классами. С другой стороны, метод equals может быть переопределен классами. Хотя его поведение по умолчанию (в классе Object ) заключается в проверке идентичности с использованием оператора == , многие классы, включая String , переопределяют вместо этого он должен сделать «эквивалентность»; проверять. В случае String вместо проверки того, ссылаются ли a и b на один и тот же объект, a.equals (b) проверяет, являются ли объекты, на которые они ссылаются, строками, которые содержат абсолютно одинаковые символы.

Время аналогии: представьте, что каждый объект String - это лист бумаги, на котором что-то написано. Допустим, у меня есть два листа бумаги с "Foo" на них написано и еще одно с "Баром" написано на нем. Если я возьму первые два листа бумаги и воспользуюсь == для их сравнения, то вернусь false , потому что по сути спрашивает "это один и тот же лист бумаги?" , Не нужно даже смотреть на то, что написано на бумаге. Тот факт, что я даю ему два листа бумаги (а не один и тот же дважды), означает, что он вернет false . Однако, если я использую equals , метод equals прочитает две бумажки и увидит, что они говорят одно и то же (" Foo "), и поэтому вернем true .

Ситуация, которая путается со строками, заключается в том, что в Java есть концепция «интернирования»; Строки, и это (эффективно) автоматически выполняется для любых строковых литералов в вашем коде. Это означает, что если в вашем коде есть два эквивалентных строковых литерала (даже если они находятся в разных классах), они на самом деле оба будут ссылаться на один и тот же объект String . Это заставляет оператор == возвращать true чаще, чем можно было ожидать.

В двух словах - у вас может быть два объекта String, которые содержат одинаковые символы, но являются разными объектами (в разных местах памяти). Оператор == проверяет, что две ссылки указывают на один и тот же объект (область памяти), но метод equals () проверяет, совпадают ли символы.

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

Да, он все время используется для тестирования. Весьма вероятно, что среда тестирования использует .equals () для таких сравнений.

Ниже приведена ссылка, объясняющая «ошибку равенства строк». По сути, строки в Java являются объектами, и когда вы сравниваете равенство объектов, обычно они сравниваются по адресу памяти, а не по содержимому. Из-за этого две строки не будут занимать один и тот же адрес, даже если их содержимое идентично, поэтому они не будут соответствовать друг другу, даже если при печати они выглядят одинаково.

http: //blog.enrii. ком / 2006/03/15 / Java-строка-равенство-синфазного ошибка /

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 ссылается на тот же экземпляр ), чего вы пытаетесь избежать.

Значит, ты в порядке.

  

" Оператор == проверяет, являются ли два Объекта одинаковыми Object . "

http://leepoint.net/notes-java/data/strings /12stringcomparison.html

String является объектом в Java, поэтому он попадает в эту категорию правил сравнения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top