Инициализация строки в Java - PullRequest
0 голосов
/ 18 января 2012

С учетом кода ниже:

  1. Как объект str1 создается без использования new String()?
  2. Почему объекты str1 и str2 ссылаются на одну и ту же область памяти?

String str1 = "hello";
String str2 = "hello";

Ответы [ 4 ]

5 голосов
/ 18 января 2012

Все это описано в спецификации языка Java.

См. 3.10.5 Строковые литералы :

Каждый строковый литерал является ссылкой (§4.3) к экземпляру (§4.3.1, §12.5) класса String (§4.3.3).Строковые объекты имеют постоянное значение.Строковые литералы или, в более общем смысле, строки, являющиеся значениями константных выражений (§15.28), являются "интернированными", чтобы обмениваться уникальными экземплярами, используя метод String.intern.

3 голосов
/ 18 января 2012

В Java вы можете создавать объекты String без вызова нового оператора. Так, String str1 = "hello" эквивалентно String str1 = new String("hello"). Это делается так, чтобы объявление строки было похоже на примитивные типы данных.

относительно того, почему они ссылаются на одну и ту же ячейку памяти:

В Java существует концепция Пул литералов строк . Чтобы сократить количество объектов String, созданных в JVM, класс String хранит пул строк. Каждый раз, когда ваш код создает строковый литерал, 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.

1 голос
/ 18 января 2012

"привет" - это строковый литерал в Java. Java создает пул строковых литералов, потому что строки неизменны и могут использоваться повторно . К new String("hello") вы будете создавать дополнительный строковый объект, даже если эквивалентный литерал уже существует в пуле.

0 голосов
/ 18 января 2012

Как подсказывает строка javadoc

String str1 = "hello";

эквивалентно

char data[] = {'h', 'e', 'l', 'l', 'o'};
String str = new String(data);

И как Спецификация языка Java предполагает, что константные строки (в данном случае "hello") String.intern ed, означающие, что они совместно используют одну и ту же память и ссылаются на одну и ту же ссылку. Все строки interend хранятся в пуле констант String (подробности см. В этом посте Определение файла библиотеки / источника, который содержит реализацию собственного метода )

строки, которые являются значениями константных выражений (§15.28) -are «интернированы», чтобы обмениваться уникальными экземплярами, используя метод

Однако, если вы создадите его с помощью 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...