Как Java обрабатывает объекты String в памяти? - PullRequest
6 голосов
/ 25 января 2012

Мне задали этот вопрос:

String s = "abc"; // creates one String object and one
          // reference variable
In this simple case, "abc" will go in the pool and s will refer to it.
String s = new String("abc"); // creates two objects,
                 // and one reference variable*

На основании вышеприведенных деталей, сколько объектов String и сколько ссылочных переменных было создано до оператора println приведенного ниже кода?

String s1 = "spring ";
String s2 = s1 + "summer ";
s1.concat("fall ");
s2.concat(s1);
s1 += "winter ";
System.out.println(s1 + " " + s2);

Мой ответ был Результатом этого фрагмента кода является весна зима весна лето

Есть две ссылочные переменные, s1 и s2. Всего было восемь объектов String создается следующим образом: «весна», «лето» (потеряно), «весна лето», «осень» (потеряно), «весна» осень "(потерян)," весна лето весна "(потерян)," зима "(потеря)," весна зима "(в этот момент" весна "потеряна).

В этом процессе не теряются только два из восьми объектов String.

Это правильно?

Ответы [ 4 ]

4 голосов
/ 25 января 2012

Ответ: 2 ссылки и 8 предметов.

String s1 = "spring "; //One reference and 1 object in string pool. (if it didn't exist already)

String s2 = s1 + "summer "; //Two references and 3 objects

s1.concat("fall "); //Two references and 5 objects

s2.concat(s1); //Two references and 6 objects

s1 += "winter "; //Two references and 8 objects

System.out.println(s1 + " " + s2);

Теперь ваш вопрос: Как Java обрабатывает строковые объекты в памяти?

Java предоставляет два способа создания объекта класса String.

  1. String str1 = "OneString";

В этом случае JVM ищет пул строк, чтобы узнать, существует ли уже эквивалентная строка. если да, возвращает ссылку на то же самое. если нет, добавляет его в пул строк и возвращает ссылку. Таким образом, новый объект может быть создан ИЛИ может не быть.

  1. String str1 = new String ("OneString");

Теперь JVM должна создать объект в куче. из-за нового . не имеет значения, присутствует ли OneString в пуле строк.

Вы также можете поместить строку в пул:

Вы можете вызвать intern () для объекта String. Это поместит объект String в пул, если его там еще нет, и вернет ссылку на объединенную строку. (Если он уже был в пуле, он просто возвращает ссылку на объект, который уже был там).

Вы можете посмотреть следующие ссылки:

Что такое пул строк Java и чем "s" отличается от новой строки ("s")?

Вопросы о пуле строк Java

1 голос
/ 25 января 2012
String s = "abc"; // creates one String object and one 
                 // reference variable 

Создает один строковый объект, только если объект уже отсутствует в пуле строковых констант.

String s = new String("abc"); // creates two objects,
                              // and one reference variable*  

Это фактически создает только один объект в куче. Он добавляет этот объект в пул тогда и только тогда, когда для этого объекта String вызывается метод intern ().

String s1 = "spring "; 
String s2 = s1 + "summer ";        
s1.concat("fall ");        
s2.concat(s1);        
s1 += "winter ";
System.out.println(s1 + " " + s2);   

Ваше объяснение выглядит нормально, за исключением того, что у вас есть еще одна строка в System.out.println (). :-)
Когда вы говорите (потеряли), это фактически означает, что он больше не является живым объектом (ссылка отсутствует в стеке).

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

Строки в Java неизменны. Выделен массив символов и некоторая окружающая информация, такая как смещение и длина. Если вы используете строковые литералы для инициализации строк, компилятор пытается оптимизировать и создает только один строковый объект для каждого литерала - это возможно, потому что они неизменны.

Если вы выполните конкатенацию или + для строк, то новая строка будет распределена, а данные скомпонованы (с потерей производительности.

В противоположность этому создание подстроки из строки практически бесплатно - данные не будут скопированы

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

выглядит правильно.Это вопрос экзамена SCJP между прочим.

concat возвращает новую строку, это потеряно.Первый s1 переопределяется "весенней зимой"

Две вещи, которые вы должны знать о строках в Java:

  • Строки являются неизменяемыми (как вы уже объясняли)
  • Строки могут находиться в пуле строк.Не каждый раз, когда вы пишете «Summer», создается полностью новая строка, неизменное «Summer» может выходить из пула (зависит от JVM, но для Oracle это так).Смотрите также: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#intern()

Приветствия Кристиана

...