Подтвердить что ты не робот

Является ли строковый литерал, хранящийся в стеке? Является ли новая строка в стеке?

Возможный дубликат:
разница между строковым объектом и строковым литералом

Скажем, у меня есть два утверждения.

String one = "abc";
String two = new String("abc");

Какая из них является памятью стека и которая хранится в куче?

В чем разница между этими двумя?

Сколько объектов создано и как ссылка в памяти?

Какова наилучшая практика?

4b9b3361

Ответ 1

Все объекты хранятся в куче (включая их атрибуты). 1

Локальные переменные (включая аргументы) всегда содержат примитивные значения или ссылки и хранятся в стеке. 1

Итак, для двух строк:

String one = "abc";
String two = new String("abc");

У вас будет два объекта в куче (два объекта String, содержащие "abc"), и две ссылки, по одному для каждого объекта, в стеке (при условии, что one и two являются локальными переменными).

(На самом деле, если быть точным, когда речь идет о интернированных строках, таких как строковые литералы, они хранятся в так называемом пуле строк.)

Сколько объектов создано и как ссылка в памяти?

Интересно, что вы спрашиваете, потому что строки являются специальными на языке Java.

Однако гарантируется одно: когда вы используете new, вы действительно получите новую ссылку. Это означает, что two не будет ссылаться на тот же объект, что и one, что означает, что у вас будут два объекта в куче после этих двух строк кода.


1) Формально говоря, спецификация языка Java не определяет, как и где значения хранятся в памяти. Это (или его вариации), однако, как это обычно делается на практике.

Ответ 2

Первый называется String Literal и создается во время компиляции программы, а второй - строковый объект и создается во время выполнения.

Как вы использовали новое ключевое слово во втором случае, так что оно выделено в кучу.

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

Ответ 3

Только экземпляры примитивных типов (int, long,...) сохраняются в стеке. Все экземпляры ссылочных типов (String, Integer, Long, YourTypeHere,...) сохраняются в куче.

ОБНОВЛЕНИЕ. Как отмечено в комментариях, ссылки на экземпляры ссылочных типов (то есть не примитивные типы - Object и его "потомки" ) могут быть сохранены в стеке. Это ваши локальные переменные.

Это не "лучшая практика", так как работает JVM, и вы не можете его изменить.

Ответ 4

В вашем случае создаются 2 объекта String. Как правило, все объекты создаются в куче. Однако, поскольку String one является строковым литералом, он будет храниться в пуле строк (в PermGen). Вы также можете использовать метод intern(), чтобы добавить строку в пул строк и получить ссылку на нее.

Если объявленные вами объявления находятся в методе, то ссылки будут сохранены в стеке, но не сами объекты.

Что касается, лучшей практики, я думаю, это будет: Строка one = "abc"

Это по двум причинам:

  • Код чище
  • Интернированные строки можно сравнить с ==, который быстрее, чем равен. Но перед тем, как сравнить его, вам понадобится intern() любую нелитеративную строку.

EDIT: Вам может быть интересно проверить эту ссылку: Escape Analysis в Java SE 7. Он представляет некоторые оптимизации, связанные с HotSpot, которые влияют на распределение объектов.