Я только что заметил, что вы ссылались на мою статью .
Спецификация Java говорит, что все в Java передается по значению. В Java нет такой вещи, как "передача по ссылке".
Ключом к пониманию этого является то, что
Dog myDog;
это не Собака; на самом деле это указатель на собаку.
Что это значит, когда у вас есть
Dog myDog = new Dog("Rover");
foo(myDog);
вы по существу передаете адрес созданного Dog
объекта методу foo
.
(я говорю по существу, потому что указатели Java не являются прямыми адресами, но проще всего так думать о них)
Предположим, объект Dog
находится по адресу памяти 42. Это означает, что мы передаем 42 методу.
если метод был определен как
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
давайте посмотрим, что происходит.
- параметр
someDog
установлен на значение 42
- по линии "ААА"
someDog
сопровождается Dog
, на которое он указывает (объект Dog
по адресу 42)
- что
Dog
(тот, что по адресу 42) просят изменить его имя на Макс
- на линии "ВВВ"
- новый
Dog
создан. Допустим, он по адресу 74
- мы присваиваем параметр
someDog
74
- в строке "CCC"
- someDog следует за
Dog
, на который он указывает (объект Dog
по адресу 74)
- что
Dog
(тот, что по адресу 74) попросили изменить его имя на Rowlf
- потом возвращаем
Теперь давайте подумаем о том, что происходит вне метода:
Изменилось ли myDog
?
Вот ключ.
Учитывая, что myDog
является указателем , а не фактическим Dog
, ответ НЕТ. myDog
все еще имеет значение 42; он по-прежнему указывает на исходный Dog
(но учтите, что из-за строки «AAA» его имя теперь «Max» - все тот же Dog; значение myDog
не изменилось.)
Совершенно верно следовать адресу и изменять то, что в конце; однако это не меняет переменную.
Java работает точно так же, как C. Вы можете назначить указатель, передать указатель на метод, следовать указателю в методе и изменить данные, на которые был указан. Однако вы не можете изменить место, на которое указывает указатель.
В C ++, Ada, Pascal и других языках, которые поддерживают передачу по ссылке, вы действительно можете изменить переданную переменную.
Если бы в Java использовалась семантика передачи по ссылке, определенный нами foo
метод изменился бы там, где указывал myDog
, когда он назначил someDog
в строке BBB.
Думайте о ссылочных параметрах как о псевдонимах для передаваемой переменной. Когда назначается этот псевдоним, то и переданная переменная.