Для сравнения строк ВСЕГДА используй метод equals()! Сравнивая строки, ты почти всегда имеешь в виду сравнение их текста, а не ссылок, областей памяти и прочего.
Метод equals() делает именно то, что тебе нужно.
Оператор ==сравнивает ссылки.
Метод equalsсравнивает значения.
Следовательно, если вы хотите сравнить строки на равенство, следует использовать equals.
Пул строк — область для хранения всех строковых значений, которые ты создаешь в своей программе.
Оператор == используется для проверки, что две строки указывают на один и тот же объект.
// Эти строки имеют одно и тоже же значениеnewString("test").equals("test")// --> true // ...но это разные объектыnewString("test")=="test"// --> false // ...эти строки тоже разные объектыnewString("test")==newString("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, вы можете воспользоваться следующим методом:
Он присутствует в некоторых сторонних библиотеках, например, в Apache Commons.
Если вы пользуетесь современными средами разработки, то они предупредят, если вы попытаетесь сравнить строки с помощью оператора ==. Всегда обращайте внимание на подобные предупреждения.
Метод String.intern()
У класса String есть еще один хитрый метод — intern(); Метод intern() напрямую работает со String Pool’ом. Если ты вызываешь метод intern() у какой-то строки, он:
Смотрит, есть ли строка с таким текстом в пуле строк
Если есть — возвращает ссылку на нее в пуле
Если же нет — помещает строку с этим текстом в пул строк и возвращает ссылку на нее.
Применив метод intern() к ссылке на строку, которая создавалась через new, мы можем сравнивать ее со ссылкой на строку из String Pool’a через оператор ==.
Вывод в консоль:
Раньше, когда мы сравнивали их без intern(), результат был равен false. Теперь же метод intern() проверил, есть ли строка с текстом "JavaRush — лучший сайт для изучения Java!" в пуле строк. Разумеется, она там есть: мы создали ее, когда написали
Была проведена проверка, что ссылка s1 и ссылка, возвращенная методом s2.intern() указывают на одну область в памяти, и, конечно, так оно и есть:)
public class Main {
public static void main(String[] args) {
String s1 = "JavaRush - лучший сайт для изучения Java!";
String s2 = new String("JavaRush - лучший сайт для изучения Java!");
System.out.println(s1 == s2.intern());
}
}
true
String s1 = "JavaRush — лучший сайт для изучения Java!";