Я просто заметил, что вы ссылались на мою статью .
Java Spec говорит, что все в Java является передачей по значению. В Java нет такой вещи, как «pass-by-reference».
Ключом к пониманию этого является то, что что-то вроде
Dog myDog;
является not собака; это на самом деле указатель для собаки.
Что это значит, когда у вас есть
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
}
let's посмотрите, что происходит.
someDog
установлен на значение 42 someDog
, после чего он Dog
указывает на точки к объекту Dog
по адресу 42), что Dog
(тот по адресу 42) предлагается изменить свое имя на Max Dog
. Предположим, что он находится по адресу 74, мы присваиваем параметру someDog
значение 74 Dog
, которое указывает (объект Dog
по адресу 74), что Dog
(тот, который находится по адресу 74), предлагается изменить его имя на Rowlf . Теперь давайте подумаем о том, что происходит вне метода: / g28]
Изменено myDog
?
Имеется ключ.
Помня, что myDog
является указателем , а не фактический Dog
, ответ НЕТ. myDog
все еще имеет значение 42; он все еще указывает на оригинал Dog
(но обратите внимание, что из-за строки «AAA» его имя теперь «Макс» - все тот же Dog, значение myDog
не изменилось.)
Совершенно верно для следовать за адресом и изменять то, что находится в конце его; что не изменяет переменную.
Java работает точно так же, как C. Вы можете назначить указатель, передать указатель методу, следовать указателю в методе и изменить данные, на которые указали. Тем не менее, вы не можете изменить, где находится этот указатель.
В C ++, Ada, Pascal и других языках, поддерживающих pass-by-reference, вы можете фактически изменить переданную переменную.
Если у Java была семантика по-ссылке, метод foo
, который мы определили выше, изменился бы там, где myDog
указывал, когда он назначил someDog
в строке BBB.
Подумайте о контрольных параметрах как как псевдонимы для переданной переменной. Когда этот псевдоним назначается, то и переменная, которая была передана.
Это была просто проблема с функцией, я передал ей 1 параметр, но ожидал 2 параметра, поэтому сборка не удалась.