Java String как получить ссылку?
Не подскажите как получить ссылку на обьект в пуле стрингов на определенную строку? Например когда мы создаем обьект его дефолтный метод toString выдает его сcылку скажем "Person@2f92e0f4", а как получить ссылку на обьект в пуле стрингов?
Updated: Я проходил собеседование в Сбербанк, и там был такой вопрос:
String s1="Hello";
String s2="Hello";
String s3=new String("Hello");
String s4=new String("Hello");
System.out.println(s1==s2);
System.out.println(s2==s3);
System.out.println(s3==s4);
Что выведется в консоль? правильный вариант ответа:
true false false
Это все было в виде теста с вариантами ответов. Насчет s1==s2 понятно ведь джава проверяет есть ли такая строка в пуле или нет, если нет создает новую, если да то просто в s2 копируется ссылка s1 на эту же строку в пуле стрингов. Но почему s3==s4 false? как посмотреть ссылки на эти обьекты?
Ответы (1 шт):
Описанный вами вопрос касался не всех объектов, а особенностей хранения строк в памяти.
Смысл в том, что строки созданные с помощью конструктора и строковые литералы хранятся немного по разному.
- Строки созданные с помощью конструктора, как и полагается, хранятся в куче(Java Heap Memory)
- Строковые литералы же хранятся в специально отведенном месте, которое называется пул строк(String Pool)
Задача String Pool - эффективная работа со строками и оптимизация их хранения.
В вашем примере
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
String s4 = new String("Hello");
Идем с начала.
- У вас появляется литерал
"Hello", который попадает в String Pool - Далее Вы кладёте в переменную s1 ссылку на
"Hello"в String Pool - Далее при использовании того же литерала
"Hello"вы получаете ту же ссылку на то же место в String Pool (и это одна из его задач: чтобы не забивать всю память одними и теми же литералами) - После чего Вы кладёте ту же ссылку на то же место в переменную s2, после чего переменные s1 и s2 хранят одинаковые ссылки, которые ведут в String Pool
- Далее Вы создаете объект с помощью конструктора и он уже размещает значение переменной не в String Pool, а в общей области Java Heap Memory
- Тоже самое происходит с переменной s4
В итоге получается, что:
Переменные s1 и s2 ссылаются на один и тот же участок памяти специально созданный для оптизации хранения строковых литералов.
А под переменные s3 и s4 выделялись отдельные участки памяти(для каждой) в куче(Java Heap Memory)
Что и соответствует выводу
true
false
false
Перемещение строк в String Pool
Также стоит понимать, что вы можете переместить строки созданные с помощью конструктора в пул строк.
Для этого есть метод intern() который перемещает строку в String Pool и возвращает ссылку на аналогичную строку в пуле, при этом если такая строка уже была в пуле, то вы получите ссылку на нее.
И если мы попробуем сделать так
String s1 = "Hello";
String s2 = "Hello";
String s3 = (new String("Hello")).intern();
String s4 = (new String("Hello")).intern();
System.out.println(s1==s2);
System.out.println(s2==s3);
System.out.println(s3==s4);
то на выводе получим, что все они равны
true
true
true
Подробнее:
