Вопрос такой. Почему при передаче методу ссылки на объект массив, происходят изменения с объектом не смотря на отсутствие возвращаемого значения. В тоже время у String никаких изменений не происходит, хотя и в том и в этом случае передается ссылка на объект.
Какой то прикол со String pool?
Korban Dallas
15 уровень
Про String и массивы
Решен
Комментарии (4)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Justinian Judge в Mega City One Master
17 августа 2021, 14:50
String immutable класс, как и классы обертки (Integer, Double и тд), то есть при любом изменении значения создается новый объект.
+ в джава нету передачи по ссылке, в джава все передается по значению, для примитивов - передается копия значения примитива, для ссылочных типов, передается значения - копия ссылки на объект.
Фактические дублируется ссылка, это как несколько пультов управления и один телевизор, с помощью копии пульта мы можем переключать каналы. Так и ссылки - ссылок может быть много, и указывать они могут на один и тот же объект.
В случае с массивами, коллекциями или сложными объектами, в которых есть поля, мы через ссылку можем менять состояние этого объекта, как ты писал за массив.
Но во втором случае:
в этой строки идет объявление локальной переменной типа String с именем name и этой переменной присваивается КОПИЯ ссылки на объект.
В итоге, у нас в программе несколько ссылок на один и тот же объект, в данном случае он находится в Стринг пуле, но это не суть важно.
в этой строке:
name = name.toUpperCase();
ты ЛОКАЛЬНОЙ переменной (то есть переменной, объявленной внутри метода, и которая не существует вне метода) присваиваешь ссылку на объект типа Стринг (мы помним, что строка неизменяемая, при любых манипуляциях создается абсолютно новый объект).
Итого, у тебя ДВЕ переменные, одна объявлена в методе main, вторая объявлена в методе changeName, это две разных переменных, в самом начале, они ссылаются на один объект, но поскольку, ты потом изменяешь объект, а Стринг - неизменяемый класс, то создается новый объект АЛИНА, о котором метод main просто не знает, он ведь никак не связан с методом.
+1
Justinian Judge в Mega City One Master
17 августа 2021, 14:50решение
Грубо говоря, вот я метод main, ты метод changeName, у меня есть Договор на банковский счет 1112. Я тебе ксерю этот договор, или делаю дубликат, и у нас у двоих есть Договор на банковский счет 1112, и мы вдвоем можем пользоваться счетом.
Ты поехал в другой город, и решил внести изменения в СВОЙ Договор (вернее в свой бланк договора), сделать так, чтобы в твоем договоре был счет не 1112, а 999.
То есть твой Бланк договора стал указывать на совсем другой счет.
Вопрос к тебе, мой договор автоматически поменяется или нет?
Ответ - нет. Ты внес изменения в свою бумажку, твоя бумажка теперь ссылается на другой счет.
Но моя не менялась, как она указывала на счет 1112, так и указывает.
Но в то же время, если не присваивать новый объект локальной ссылке (методу) то с помощью этой ссылки можно менять объект - например с дубликатом на счет 1112 можно снимать деньги, класть, менять и тд, но новый счет - новая история и она будет касаться только локальную переменную
+2
Korban Dallas
17 августа 2021, 18:26
Спасибо большое за такой подробный ответ💜
0
Ksenia Volkova Java Developer в DXC Master
17 августа 2021, 14:48решение
Класс String - immutable, неизменяемый. Созданный объект String невозможно изменить, можно только создать новый.
Метод toUpperCase() - как и все методы, работающие со строками - не меняет исходный объект, а возвращает новый. Ссылка на этот новый объект в данном случае помещается в локальную переменную name метода changeName(). Но объект, ссылка на который хранится в переменной name из main, никак не меняется.
+2