Как 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
,
- String str1 = "OneString";
В этом случае JVM ищет пул строк, чтобы увидеть, существует ли уже эквивалентная строка. если да, возвращает ссылку на то же самое. если нет, добавляет его в пул строк и возвращает ссылку. Таким образом, новый объект может быть создан ИЛИ может не быть.
- String str1 = new String ("OneString");
Теперь JVM должна создать объект в куче. из-за нового. не имеет значения, если OneString
уже присутствует в пуле строк.
Вы также можете поместить строку в пул:
Вы можете вызвать intern() для объекта String. Это поместит объект String в пул, если его там еще нет, и вернет ссылку на объединенную строку. (Если он уже был в пуле, он просто возвращает ссылку на объект, который уже был там).
Вы можете посмотреть на следующие ссылки:
Что такое пул строк Java и чем "s" отличается от новой строки ("s")?
Выглядит правильно. Это вопрос экзамена 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().:-)
Когда вы говорите (потерял), это на самом деле означает, что он больше не является живым объектом (ссылка отсутствует в стеке).