Новая строка Java и новый StringBuilder в поведении кучи

  1. Пул строк находится в куче? Если да, подходят ли строковые литералы для сборки мусора?

При использовании new String("abc") мы знаем, что он создает объект в куче и помещает строковый литерал в пул строк. Итак, мой второй вопрос:

  1. new StringBuilder("abc") ведет себя так же, как new String("abc")? Если да, то как StringBuilder управляет строковым литералом внутри пула строк?

person Ryan    schedule 25.01.2015    source источник
comment
как StringBuilder управляет строковым литералом внутри пула String StringBuilder не управляет строковым литералом из пула, но копирует весь символ из литерала в свой собственный буфер, которым затем можно управлять.   -  person Pshemo    schedule 25.01.2015
comment
Когда вы делаете new String("abc"), строковый литерал уже находится в пуле интернированных строк.   -  person Hot Licks    schedule 25.01.2015


Ответы (2)


Вы путаете время компиляции, время загрузки и время выполнения.

Строковый литерал добавляется в пул констант во время загрузки класса. Достаточно просто упоминания литерала в любом месте кода класса; вам даже не нужно выполнять какую-либо строку кода в этом классе.

С другой стороны, выражение new String("literal") возвращает новый String экземпляр при каждой оценке. Этот экземпляр отличается от экземпляра в пуле констант и имеет копию строкового значения.

StringBuilder в этом отношении действует точно так же, как String: он инициализируется копией значения строкового литерала.

person Marko Topolnik    schedule 25.01.2015
comment
Последний абзац может быть неправильно понят. На самом деле происходит то, что символы аргумента конструктора копируются в char [], который используется для хранения символов сборки. - person laune; 25.01.2015
comment
@laune Мне интересно услышать неверно понятую версию. То, что вы написали, для меня звучит как пересказ моего предложения, более ориентированный на реализацию. - person Marko Topolnik; 25.01.2015
comment
Возможно, я здесь чересчур чувствителен, но я подумал, что кто-то может подумать, что StringBuilder на самом деле хранит объекты String. может быть инициализирован из буквального значения строки. Но, как я уже писал, возможно ... - person laune; 25.01.2015
comment
@laune Я понимаю, что ты имеешь в виду. То, что я считаю ценностью, может быть запутано. - person Marko Topolnik; 25.01.2015

Во-первых, да, пул строк и содержащиеся в нем строки находятся в куче. Как только строковый литерал попадает в пул строк, он никогда не будет из него удален. Таким образом, все строковые литералы в пуле строк доступны до завершения программы и, следовательно, не имеют права на сборку мусора. (Строки, добавленные в пул строк другими способами, могут иметь право на сборку мусора.)

Если мы создадим новый объект String с помощью new String("abc"), то произойдут две вещи: во-первых, из-за строкового литерала «abc» создается новый объект String с содержимым «abc» и добавляется в пул строк (если его там еще нет. ). Затем из-за конструктора new String(...) создается новый объект String, который является копией строкового литерала. Эта новая строка не помещается в пул строк. Таким образом, new String("abc") == "abc" не выполняется.

Код new StringBuilder("abc") не делает то же самое, что и new String("abc"), потому что он создает объект StringBuilder, а не String. Однако из-за строкового литерала «abc» он гарантирует, что объект String с содержимым «abc» находится в пуле строк.

person Hoopje    schedule 25.01.2015
comment
_1 _--- неправда. Даже строковые литералы могут стать недоступными, если класс выгружен. Строки, явно intern отмеченные во время выполнения, становятся мусором так же, как и обычные строки (ссылка на них внутри пула является слабой). - person Marko Topolnik; 25.01.2015
comment
@MarkoTopolnik. Спасибо за исправление. Я отредактировал ответ. - person Hoopje; 25.01.2015