Ваш первый образец не изменяет переменную someThing
в вызывающей программе. Назначение отображается только в методе doSomething
.
Второй образец изменяет someThing
в вызывающем.
Так что, если вы хотите изменить someThing
в вызывающем абоненте, вариант 2 является жизнеспособным, а вариант 1 - нет.
См. Is Java "pass-by-reference" or "pass-by-value"?, почему это работает именно так.
Предполагая следующий код и Thing
, который имеет метод печати и элемент String.
void foo() {
Thing one = new Thing("hello"); // 1
bar(one);
one.print(); // 5
}
void bar(Thing two) { // 2
two = new Thing("bye"); // 3
} // 4
Отнесение в точке 1
первый создает новый объект Thing:
Thing{data="hello"}
Затем хранит ссылку на что в one
:
one *----- refs --------v
Thing{data="hello"}
При входе bar
в точке 2
, создается новая ссылка на тот же объект:
one *----- refs --------v
Thing{data="hello"}
two *----- refs --------^
Далее строка 3
делает то же самое, как линии 1
, то есть создать новый Thing
объект:
one *----- refs --------v
Thing{data="hello"}
two *----- refs --------^
Thing{data="bye"}
затем сохраняет ссылку на этот новый объект в two
:
one *----- refs --------v
Thing{data="hello"}
two *----- refs --------v
Thing{data="bye"}
Обратите внимание, что только two
модифицировано. Назначение изменяет то, что означает two
. не
После возвращения из bar
, в строке 4
, two
выходит из области видимости, то «прощайте» Вещь не имеет ничего ссылающегося его (и в конечном счете мусора).
one *----- refs --------v
Thing{data="hello"}
Thing{data="bye"} // dead, will be collected
Таким образом, в точке 5
, как вы можете видеть, hello
будет печататься - никогда ничего не изменил объект, который one
относится.
Ооооооооооооооооооооооооооооооооооооооооооооооолно здесь – Theodor
_why_ это? Это потому, что я переписываю также ссылку на 'someThing' в первом случае? – Theodor