someThing
最初のサンプルでは、呼び出し元の変数は変更されません。割り当てはdoSomething
メソッドでのみ表示されます。
2番目のサンプルはsomeThing
、呼び出し元で変更されます。
したがって、発信者を変更したい場合someThing
は、オプション2が実行可能ですが、オプション1は実行可能ではありません。
Javaは「参照渡し」または「値渡し」ですか?を参照してください。なぜこれがそのように機能するのか。
次のコードを想定しThing
、printメソッドとStringメンバーを持つa。
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 --------^
次に、line3
はlineと同じことを行います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
。参照するオブジェクトは何も変更されていません。