По-идее, если передать в метод значение Integer, то он должен поменять значение переменной. Но почему этого не происходит, как рассказывают в теории?
CrazyKISS
19 уровень
Передача int и Integer в методы
Решен
Комментарии (7)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
hidden #598481
14 сентября 2022, 07:42
Нет, всё работает не совсем так.
Ссылочная переменная содержит ссылку на объект. Это тезис, вокруг которого строится всё объяснение.
У тебя есть две локальные переменные с именем value2, одна в методе main, одна в методе change. Их, кстати, необязательно называть одинаково, можно как угодно. Оператор "=" означает операцию присваивания, то есть тут
ты присваиваешь переменной ссылку на объект, связанный с числом 33.
Когда ты передаёшь объект в параметре при вызове метода, под капотом происходит присваивание значения аргументу этого метода, условно говоря так То есть после вызова метода эти переменные начинают ссылаться на один и тот же объект.
Дальше ты выполняешь в этом методе команду То есть переменная внутри change начинает ссылаться на другой объект, в этой переменной изменилось содержимое, но никакого влияния на содержимое переменной из метода main это не оказывает. Теперь каждая переменная просто ссылается на разные объекты, одна на 33, другая на 22, и всё. И можно запомнить как правило, что если ты используешь где-то операцию "=", то это значит, что у тебя переменная перестала ссылаться на тот объект, на который она ссылалась раньше, а теперь ссылается на какой-то другой, то есть прежняя ссылка из переменной потеряна.
Я понимаю, что ты хотела сделать своим экспериментом, но выбрала неподходящий класс. Дело в том, что объекты класса Integer - неизменяемые (immutable). Это не какая-то специальная аннотация или ключевое слово в этом классе, нет, просто в этом классе нет ни одного метода, который мог бы изменить состояние этого объекта.
Продолжение ниже +1
hidden #598481
14 сентября 2022, 07:56
Так вот, про состояние.
Нельзя сделать примерно так:
Если бы так было можно, ты могла бы вторую строчку вынести в отдельный метод и увидеть, что объект действительно изменил своё состояние, т.е. принял новое значение, сохранив свою ссылку.
Но никакого метода add нет, каждый объект Integer всегда связан только с одним числом. Если хотеть связать его с другим числом, то просто ты получишь другой объект Integer, а не изменённый первый.
То есть Integer нужны не для того, чтобы производить над объектами какие-то операции и изменять их. Обёртки по большому счёту нужны только для того, чтобы переменные могли не иметь значения, т.е. быть null, и чтобы их можно было хранить в коллекциях.
Точно такая же ситуация со строками, они тоже неизменяемые.
Если написать То это никак не повлияет на содержимое строки s, её никак не обрежешь.
А если написать дальше s = ... то переменная s просто начнёт ссылаться на другой объект, а предыдущий объект "abc" посто выкинется в сборщик мусора.
Вместо этого ты могла бы провести эксперимент, например, с массивом: передать массив в метод, изменить его содержимое и увидеть, что массив в методе main тоже поменялся. На эту тему здесь есть хорошая задачка, в которой надо написать метод sort(int[] array), в котором отсортировать массив в порядке убывания. Некоторые пытаются решать её так, что создают в методе копию массива, сортируют её при помощи Array.sort, а потом присваивают аргументу ссылку на копию: И удивляются, почему в методе main массив не изменился. Но ты же теперь знаешь, почему? +1
CrazyKISS
14 сентября 2022, 07:57
спасибо за объяснение!
Я знала, что это относится к типу String, но насчёт Integer - для меня это открытие.
Это касается всех типов-оберток?
0
hidden #598481
14 сентября 2022, 08:03
да.
+2
CrazyKISS
14 сентября 2022, 08:17
Большое спасибо! Прям глаза открылись :))))
+1
Денис Enterprise Java Developer
14 сентября 2022, 07:41
Параметры в метод передаются по значению. Для ссылочных типов значение есть ссылка на объект, по этому если объект модифицируется - изменения видны снаружи метода. Для примитивов значение это просто значение.
Ну и конечно-же, твоя реализация просто присвоила другую ссылку переменной внутри метода, это никак не повлияло бы на состояние оригинального объекта.
+2
CrazyKISS
14 сентября 2022, 07:58
поняла, спасибо!
Думала, если передать по ссылке, то можно менять сам объект.
0