Вопрос по строкам в Java

161
23 апреля 2019, 20:40

Пример кода:

String s = "abcd";

Тут мы явно указываем, что в переменной s хранится ссылка на объект. Сам объект неизменяемый, например, при вызове метода substring() для s, создается новая строка (обьект).

Второй пример кода:

if (s.substring(1).equals("j")) {
...
}

Вопрос:

  1. Где хранятся и хранятся ли вообше ссылки на объекты s.substring(1) и "j", так как явно мы не сохранили их в каких либо переменных.

  2. Что происходит с этими строками после того как метод отработает, уничтожаются ли они сборщики мусора, так как, например, если этот if будет в теле цикла и на каждом шагу s.substring() будет создавать строки, которые !equals() между собой (чтобы в пуле были разные строки), то это же лишняя трата памяти.

Answer 1

Где хранятся и хранятся ли вообше ссылки на объекты s.substring(1) и "j", так как явно мы не сохранили их в каких либо переменных.

"j" — литерал (строковая константа), соответственно, при загрузке класса автоматически интернируется и попадает в пул строк, где и хранится. На строку будет хранится ссылка из класса, в котором она объявлена, соответственно, она не будет доступна сборщику мусора пока сам класс не будет выгружен из виртуальной машины.

s.substring(1) — создает новый объект, ссылка на который нигде не хранится. Динамически созданные строки собираются сборщиком мусора, как и любые другие объекты. Кстати, при таком вызове будет выбрана строка без первой буквы, а не первая буква.

Создание новых объектов можно отследить с помощью такого кода (Динамически созданную строку можно принудительно поместить в пул, с помощью метода String.intern.):

String s = "hello";
//false, строка такая же, но substring создает новый объект
System.out.println(s.substring(0,1)=="h");
//false, оба раза substring создает новый объект
System.out.println(s.substring(1,2)==s.substring(1,2));
//true, получили ссылку на строку из пула
System.out.println(s.substring(0,1).intern()=="h");
//true, поместили строку в пул
System.out.println(s.substring(1,2).intern()==s.substring(1,2).intern());

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

Что происходит с этими строками после того как метод отработает, уничтожаются ли они сборщики мусора, так как, например, если этот if будет в теле цикла и на каждом шагу s.substring() будет создавать строки, которые !equals() между собой (чтобы в пуле были разные строки), то это же лишняя трата памяти.

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

Похожие вопросы на английском:

  • Garbage collection on intern'd strings, String Pool, and perm-space
  • Garbage collection behaviour for String.intern()
READ ALSO
Как создавать кнопки динамически?

Как создавать кнопки динамически?

Подскажите как создать кнопки в jPanel при нажатии другой кнопки(Нажимаю кнопку, и на jPanel создается новая кнопка jButton1, нажимаю еще раз jButton2, и т

171
Что я делаю не так? (Архиватор)

Что я делаю не так? (Архиватор)

Учу Java, решил написать что-то типа архиватораСобственно в output вводим путь и название архива, типа : C://Folder/arhiv

143
Exception in thread “main” java.util.NoSuchElementException

Exception in thread “main” java.util.NoSuchElementException

При компиляции следующего кода на hyperskillorg выскакивает ошибка данного характера :

151