他の回答からわかるように、Javaは純粋に値渡しです。オブジェクトは、「値参照」と呼ばれるものによって渡されます。Javaのオブジェクトは単なるポインタ参照であるため、「値」はオブジェクトがヒープ上に存在するアドレスと考えることができます。したがって、メソッド呼び出しを行うときは、「値」、別名アドレスをメソッドパラメーターにコピーします。
Object x = new Object();
foo(x);
オブジェクト作成中
ヒープ->オブジェクトの割り当て(5000)
変数宣言
スタック->ローカル変数の割り当て(1000)
変数の割り当て
スタックアドレス1000を5000に設定(オブジェクトインスタンスを指すため)
したがって、ここには2つの別々のメモリ割り当てがあることがわかります。変数の「値」は、ヒープ上のアドレスと見なされます。
メソッド呼び出し
スタック->メソッドパラメータ8000の割り当て
スタックアドレス8000は、渡されたパラメータ5000と同じ値に設定されます
これが、メソッドでオブジェクトインスタンスを再割り当てした場合、それが呼び出し元に伝播されない理由です。スタック位置8000のヒープ位置を変更したはずです。また、呼び出し元のメソッドのスタック位置1000の値は5000(元のオブジェクトインスタンス)のままです。
Cでは次のように考えてください。
void method(myobject * obj);
あなたは確かに"obj"のフィールドを変更することができます、そしてあなたはこれをローカルで行うことができます:
obj = new myobject();
ただし、呼び出し元には、渡された元の値が引き続き表示されます。
Javaには、&reference演算子に類似したものはありません。
そして、あなたの目的のために使用できる組み込みのクラスがあります。AtomicInteger、AtomicLongなどは変更可能ですが、同期が関係しているためにパフォーマンスが低下する可能性があります。
参照によるパスをシミュレートするすべての状況を説明するために、汎用のValueHolderクラスをお勧めします。
public class ValueHolder<T> {
private T value;
// getter/setter/constructor
}