Прочел я в объяснениях старших товарищей, что "String s1 = new String("JavaRush") не записывает значение в пул строк, а s1 = "JavaRush" - да"...
Нигде я не нашёл подтверждающей это информации, но размышлизмы привели меня к следующим умозаключениям:
Что бы мы не раскомментировали, в сравнении equals мы всегда получим true. А вот при ==, когда сравниваются ссылки, результат уже будет зависеть от выбранного варианта.
Так вот, если мы раскомментируем третий вариант, то сразу получим новый объект с новой ссылкой, которая не == s1.
А вот второй вариант... Казалось бы, какое отношение он имеет к сравнению ссылок, если сравниваются s1 и s3. Но именно после появления String s2 = new String("JavaRush") все последующие инициализации со значением "JavaRush" будут ссылаться на более "свежую" строку "JavaRush" из пула, то есть на s2 - s3 получит ссылку на тот же объект, что и s2. То есть в пуле строк будут две ячейки "JavaRush", но на первую будет ссылаться только s1, а на вторую s2 и s3. Именно поэтому s1==s3 - false.
А вот, когда мы раскомментируем первый вариант, то мы в s1 передадим уже существующую у него ссылку. Как буд-то бы мы написали:
int a = 5;
int a = 5;
Именно поэтому первый вариант ничего нового не вносит и даёт возможность s2 и s3 сослаться на ту же ячейку.
Верны ли мои умозаключения?
Dmitriy Kvitka
31 уровень
Верно ли понимание?
Решен
Комментарии (3)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Eugene Volkov
22 сентября 2025, 21:29
чел, спасибо тебе большое. чуть себе весь мозг не сломал,пытаясь понять почему не работает в любом случае или вообще без раскомментирования. а так объяснил нормально
0
ГоффMaster
8 января 2023, 16:20решение
Не видя вариантов конечно трудно что-либо сказать. Попробую угадать, о чём ты:
Если стринговая переменная инициализируется литералом ("Test string"), то она попадает в пул. Если стринговая переменная инициализируется как объект класса String, то это будет новый объект и в пул строка не попадает.
Если стринговая переменная инициализируется выражением, то в пул она тоже не попадает. Потому что в пул строки помещаются на стадии компиляции, а не в процессе выполнения, когда высчитываются выражения. НО! Есть метод intern(), который в процессе выполнения принудительно запихивает строку в пул.
Вот пример, все переменные имеют одинаковое значение, переменная a указывает на пул, если другая переменная тоже в пуле, то на вывод выдаст true
+5
Dmitriy Kvitka
8 января 2023, 18:47
Для наглядности часть задачного кода:
public static void main(String[] args) {
String s1 = new String("JavaRush");
// s1 = "JavaRush";
String s2 = "JavaRush";
// s2 = new String("JavaRush");
String s3 = "JavaRush";
// s3 = new String("JavaRush");
System.out.println(s1 == s3);
System.out.println(s2.equals(s3));
}
Нужно раскомментировать одну из строк.
Выводиться должно:
true
true
Из вашего развернутого ответа подчерпнул много нового для себя. Очень благодарен!
Выходит, что если мы раскомментируем первый вариант, то выражение s1 = "JavaRush" не попадет в пул, потому что в процессе компиляции эта переменная не будет еще инициализирована. В пул попадет s2, а s3 сошлется на эту же ячейку, то есть их ссылки будут равны.
И вот в процессе работы кода создастся объект s1 и после этого ему присвоится значение "JavaRash", ссылающееся на ячейку из пула, которую там сохранила s2 и на которую ссылается s3. То есть в итоге не s3 ссылается на ячейку в пуле, созданную s1(как я думал ранее), а s1 ссылается на ячеку, созданную s2.
А когда мы раскомментируем второй вариант, компиляция проходит так же, по предыдущему сценарию, но при работе кода создается переменная s1 со ссылкой на новый объект, переменной s2 присваивается новая ссылка на новый объект, а s3 остается хранить ссылку на ранее созданную s2 ячейку. Вот и выходит, что у каждой переменной своя ссылка.
Ну а в третьем варианте картина схожая со вторым.
Как-то так🤷🏻♂️
Гофф, еще раз спасибо большое!
+2