Оператор ==
сравнивает ссылки.
Метод equals
сравнивает значения.
Следовательно, если вы хотите сравнить строки на равенство, следует использовать equals
.
Однако в некоторых случаях строки гарантированно представлены одним и тем же объектом благодаря пулу строк (string interning). Эти случаи явно описаны в спецификации языка Java.
Оператор ==
используется для проверки, что две строки указывают на один и тот же объект.
// Эти строки имеют одно и тоже же значение
new String("test").equals("test") // --> true
// ...но это разные объекты
new String("test") == "test" // --> false
// ...эти строки тоже разные объекты
new String("test") == new String("test") // --> false
// ...но эти строки указывают на один и тот же объект,
// потому что компилятор добавляет все литералы в пул.
"test" == "test" // --> true
// Конкатенация литералов тоже происходит на стадии компиляции,
// поэтому они указывают на один объект
"test" == "te" + "st" // --> true
// но вызов substring() происходит во время выполнения,
// в результате получаются разные объекты.
"test" == "!test".substring(1) // --> false
// Строки из пула могут быть получены с помощью вызова intern().
"test" == "!test".substring(1).intern() // --> true
Надо отметить, что ==
заметно быстрее, чем equals
(сравнение ссылки вместо вызова метода и посимвольного сравнения, если строки разной длины), поэтому, если вы работаете со строками из пула (или системного, или своего), замена equals
на ==
может привести к заметному ускорению. Но это случается очень редко.
Остерегайтесь вызова equals
на null
! Оператор ==
прекрасно сравнивает строки, если одна или более из них равна null
, но вызов метода equals
на строке, равной null
, приведёт к исключению.
Для сравнения строк, которые могут быть равны null
, вы можете воспользоваться следующим методом:
public static boolean equals(String str1, String str2) {
return str1 == null ? str2 == null : str1.equals(str2);
}
Он присутствует в некоторых сторонних библиотеках, например, в Apache Commons.
Если вы пользуетесь современными средами разработки, то они предупредят, если вы попытаетесь сравнить строки с помощью оператора ==
. Всегда обращайте внимание на подобные предупреждения.