Учитывая приведенный ниже код:Строка инициализации в Java
- Как это
str1
объект, созданный без использованияnew String()
? - Почему объекты
str1
иstr2
ссылаются на эту ячейку памяти?
String str1 = "hello";
String str2 = "hello";
Учитывая приведенный ниже код:Строка инициализации в Java
str1
объект, созданный без использования new String()
?str1
и str2
ссылаются на эту ячейку памяти?String str1 = "hello";
String str2 = "hello";
Все это описано в спецификации языка Java.
Каждая строка буквальным является ссылкой (§4.3) к экземпляру (§4.3.1, §12.5) класса String (§4.3.3). Объекты String имеют постоянное значение. Строковые литералы - или, в более общем смысле, строки, которые являются значениями констант (§15.28) - «интернированы», чтобы разделить уникальные экземпляры , используя метод String.intern.
"hello" - это строковый литерал на Java. Java создает пул строковых литералов, потому что строки являются неизменяемыми и многоразовыми. К new String("hello")
вы создадите дополнительный строковый объект, хотя эквивалентный литерал уже существует в пуле.
В java вы можете создавать объекты String без вызова нового оператора. Таким образом, String str1 = "hello"
эквивалентен String str1 = new String("hello")
. Это делается так, чтобы сделать объявление строки похожим на примитивные типы данных.
относительно того, почему они со ссылкой на то же место памяти:
В Java есть понятие String literal pool .Чтобы сократить количество объектов, созданных Струнные в JVM, класс Строка сохраняет пул строк , Каждый раз, когда ваш код создает строковый литерал, JVM сначала проверяет пул строк. Если строка уже существует в пуле, возвращается ссылка на объединенный экземпляр. Если строка не существует в пуле, создается новый объект String, а затем помещается в пул.
String str1 = "Hello";
String str2 = "Hello";
System.out.print(str1 == str2);
Печать True
.
Если вы:
String str1 = "Hello";
String str2 = new String("Hello");
System.out.print(str1 == str2);
Печать False
.
потому что объект String создан из строкового литерала пула.
Как string javadoc предлагает
String str1 = "hello";
эквивалентно
char data[] = {'h', 'e', 'l', 'l', 'o'};
String str = new String(data);
И Как Java Language Specification предлагает Фиксированные строки (в данном случае "hello"
) являются String.intern-е изд означает, что они разделяют ту же память и относятся к той же ссылке , Все строки interend хранятся в струнном постоянном пуле (см этого поста для деталей Identify library file/Source that contains native method implementation)
строк, которые являются значением постоянных выражений (§15.28) -Есть «интернировано» с тем, чтобы разделить уникальные экземпляры, используя метод
Однако если создать его с new String()
себя, новая память будет выделена
String str = "hello";
String str1 = new String(str);
String str2 = new String(str);
assert: str1 != str2;
//Force strings into constant pool
String str3 = str1.intern();
String str4 = str2.intern();
assert: str == str3;
assert: str3 == str4;
Как вы знаете, '' str1' и str2' точку в той же ячейке памяти? Вы проверили это? – paislee
@ paislee да, я протестировал его. – invariant