Основы Java: понимание равенства строк
В этой статье мы покажем, как сравнивать строки в Java на равенство, и обсудим некоторые из распространенных ошибок, с которыми сталкиваются разработчики на этом пути.
Использование метода equals()
Класс String содержит метод equals()
, который используется для определения того, являются ли две строки одинаковыми. Он возвращает логическое значение.
Давайте посмотрим на код, использующий этот метод:
Object obj = new Object();
String test1 = obj.toString();
String test2 = obj.toString(); System.out.println(test1.equals(test2)); // true
Иногда мы можем не заботиться о чувствительности к регистру. В этой ситуации мы можем использовать метод equalsIgnoreCase()
:
String name1 = "Amir";
String name2 = "aMiR"; System.out.println(name1.equalsIgnoreCase(name2)); // true
Как избежать исключений с помощью equals()
Сравнивая строковую переменную с литералом, мы можем записать ее несколькими способами:
String name = "Amir";
System.out.println(name.equals("Amir")); // true System.out.println("Amir".equals(name)); // true
Обратите внимание на строку 3, как мы поменяли местами порядок строкового литерала и переменной. Это законный и на самом деле предпочтительный подход по сравнению со строкой 2.
Почему?
Потому что он не выдаст NullPointerException
, если наша переменная имени окажется нулевой. Он просто вернет false
, что обычно нам и нужно.
Давайте взглянем на код, демонстрирующий этот факт:
String name = null;
System.out.println("Amir".equals(name)); // false System.out.println(name.equals("Amir")); // NullPointerException
Почему бы не использовать оператор ==?
Хотя оператор == можно безопасно использовать для сравнения примитивных целых чисел, его использование для строк является ошибкой.
Когда операнды являются объектами, оператор == сравнивает их ссылки или то, где они хранятся в памяти. Он не проверяет значение, хранящееся в этих объектах.
Давайте создадим объект и получим его строковое представление, чтобы увидеть, как ведет себя оператор.
Object obj = new Object();
String test1 = obj.toString();
String test2 = obj.toString();
System.out.println(test1 == test2); // false
Обратите внимание, что мы присвоили обеим строкам одно и то же значение, но наша проверка на равенство по-прежнему возвращала false
.
Оператор проверяет, являются ли они тем же объектом в памяти, которым они не являются.
Предупреждение о строковых литералах
Смущает то, как ведет себя Java, когда оператор == используется для строковых литералов.
String name1 = "Amir"; String name2 = "Amir";
System.out.println(name1 == name2); // true
Оператор на самом деле ведет себя так, как ожидалось, и возвращает true!
Причина этого в том, что Java поддерживает пул литеральных объектов String для экономии памяти. Это закулисный процесс, называемый стажировкой, который выходит за рамки этой статьи.
Итак, в примере кода обе переменные фактически указывают на один и тот же объект в памяти.
Вывод
Всегда используйте методы equals()
или equalsIgnoreCase()
для равенства строк в Java. Это уменьшит вероятность создания в коде незаметных ошибок, которые трудно обнаружить.
Первоначально опубликовано на www.codebyamir.com 20 февраля 2018 г.