Java Spec は、Java のすべてが値渡しであると述べています。Javaには「参照渡し」というものはありません。
これを理解するための鍵は、次のようなものです
Dog myDog;
犬ではありません。実際には、Dog へのポインタです。
それが意味するのは、あなたが持っているときです
Dog myDog = new Dog("Rover");
foo(myDog);
基本的に、作成された Dog オブジェクトのアドレスを foo メソッドに渡しています。
(基本的に b/c Java ポインターは直接アドレスではないと言いますが、そのように考えるのが最も簡単です)
Dog オブジェクトがメモリ アドレス 42 にあるとします。これは、メソッドに 42 を渡すことを意味します。
メソッドが次のように定義されている場合
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
何が起こっているのか見てみましょう。
- パラメータ someDog は値 42 に設定されています
- 行「AAA」で
- someDog は、それが指す Dog (アドレス 42 の Dog オブジェクト) に続きます。
- その犬 (アドレス 42 の犬) は、名前をマックスに変更するように求められます。
- 行「BBB」で
- 新しい犬が作成されます。彼が住所74にいるとしましょう
- パラメータsomeDogを74に割り当てます
- 行「CCC」
- someDog は、それが指す Dog (アドレス 74 の Dog オブジェクト) に続きます。
- その犬 (アドレス 74 の犬) は、名前を Rowlf に変更するように求められます。
- その後、戻ります
次に、メソッドの外側で何が起こるかを考えてみましょう。
myDog は変更されましたか?
鍵があります。
myDog はポインターであり、実際の Dog ではないことに注意してください。答えは NO です。myDog の値は 42 のままです。まだ元の Dog を指しています。
アドレスをたどって、その末尾にあるものを変更することは完全に有効です。ただし、変数は変更されません。
Java は C とまったく同じように機能します。ポインターを割り当て、ポインターをメソッドに渡し、メソッド内でポインターをたどり、ポイントされたデータを変更できます。ただし、そのポインターが指す場所を変更することはできません。