Как Java обрабатывает объекты String в памяти?

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

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 ответа

Решение

Ответ: 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 обрабатывает объекты String в памяти?

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

  1. String str1 = "OneString";

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

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

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

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

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

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

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

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

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

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

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

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

Ура христианская

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

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

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

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().:-)
Когда вы говорите (потерял), это на самом деле означает, что он больше не является живым объектом (ссылка отсутствует в стеке).

Другие вопросы по тегам