Каково различие между этими двумя следующими утверждениями?
String s = "text";
String s = new String("text");
new String("text");
явно создает новый и ссылочно отличный экземпляр объекта String
; String s = "text";
может повторно использовать экземпляр из пула строковых констант, если он доступен.
Вы очень редко захотите использовать конструктор new String(anotherString)
. Из API:
String(String original)
: Инициализирует вновь созданныйобъект String
так, чтобы он представлял ту же последовательность символов, что и аргумент; другими словами, вновь созданная строка является копией строки аргумента. Если не требуется явная копия оригинала, использование этого конструктора не нужно, поскольку строки неизменяемы.
Изучите следующий фрагмент:
String s1 = "foobar";
String s2 = "foobar";
System.out.println(s1 == s2); // true
s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
==
на двух ссылочных типах - это сравнение ссылочной идентичности. Два объекта, которые равны
, не обязательно ==
. Обычно неправильно использовать ==
для ссылочных типов; чаще всего вместо этого нужно использовать equals
.
Тем не менее, если по какой-то причине вам нужно создать две равные
, но не ==
строки, вы можете использовать конструктор new String(anotherString)
. Однако следует повторить, что это очень своеобразно и редко является намерением.
Один создает строку в пуле констант строк
String s = "text";
, другой создает строку в пуле констант ( «текст»
) и другую строку в нормальное пространство кучи ( s
). Обе строки будут иметь то же значение, что и «текст».
String s = new String("text");
s
затем теряется (имеет право на GC), если позже не используется.
С другой стороны, строковые литералы используются повторно. Если вы используете «текст»
в нескольких местах вашего класса, на самом деле это будет одна и только одна строка (т.е. несколько ссылок на одну и ту же строку в пуле).
Ниже приведен простой способ понять разницу: -
String s ="abc";
String s1= "abc";
String s2=new String("abc");
if(s==s1){
System.out.println("s==s1 is true");
}else{
System.out.println("s==s1 is false");
}
if(s==s2){
System.out.println("s==s2 is true");
}else{
System.out.println("s==s2 is false");
}
output is
s==s1 is true
s==s2 is false
Таким образом, new String () всегда будет создавать новый экземпляр.
Подумайте о «bla»
как о волшебной фабрике, такой как Strings.createString («bla»)
(псевдо). Фабрика хранит пул всех строк, созданных таким образом.
Если он вызывается, он проверяет, есть ли уже в пуле строка с этим значением. Если true, он возвращает этот строковый объект, следовательно, полученные таким образом строки действительно являются одним и тем же объектом.
В противном случае он внутренне создает новый строковый объект, сохраняет его в пуле и затем возвращает. Таким образом, когда в следующий раз запрашивается то же строковое значение, он возвращает тот же экземпляр.
Создание новой строки ("")
вручную отменяет это поведение путем обхода пула строковых литералов. Таким образом, равенство всегда следует проверять с помощью equals ()
, который сравнивает последовательность символов вместо равенства ссылки на объект.
Хотя с точки зрения программиста он выглядит одинаково, он оказывает большое влияние на производительность. Вы бы хотели использовать первую форму почти всегда.