Java での参照渡し

Aryan Tyagi 2023年10月12日
Java での参照渡し

ポインタは、特定のデータのアドレスを暗黙的に監視するプログラミング言語アーキテクチャの変数です。別の変数に相当するものは、参照と呼ばれます。参照変数に加えられた変更は、元の変数に直接影響します。

Java は値渡し言語です。仕様では、それ自体が参照渡し言語ではなかったと述べています。Java では、参照の性質があいまいであるため、2つの用語の間に多くの混乱が存在します。この記事でそれを解決しようとします。

値渡しについて説明しましょう。ここで、仮パラメータの値は、メソッド/関数の実行中にそれを格納するために使用される場所にコピーされます。この場所には通常、その目的のために割り当てられたメモリのチャンクがあります。

参照渡しでは、仮パラメーターの値は、メソッド/関数の実行中にパラメーターを格納するために使用される場所にコピーされます。この場所には通常、その目的のために割り当てられたメモリのチャンクがあります。

Java は堅牢で安全な言語として宣伝されており、Java の利点の 1つは、C++ のようなポインターを有効にしなかったことです。彼らはその概念に別の用語を選び、公式には参照と呼んでいました。

これを把握するための鍵は、次のようなことを検討することです。

Object Obj;

これは、Obj ではなく、Object へのポインタです。参照という用語は Java で誤解されており、ほとんどの混乱の原因となっています。他のプログラミング言語では、参照と呼ばれるものがポインターとして機能します。

Java のオブジェクトについて話すときは、参照と呼ばれるオブジェクトハンドルについて話します。これも値によって提供されます。

上記のコードでは、構築された Object アドレスをメソッドに効果的に送信しています。

Java は、手続き型言語であるという点で C に似ています。メソッドへのポインターを割り当て、そこに送信し、メソッド内でトレースし、ポイントしたデータを変更できます。一方、ポインタの位置に加えた変更は、呼び出し元に気付かれません。(参照渡し言語では、メソッド関数は呼び出し元が気付かないうちにポインターを変更できます。)

渡された変数の代わりに参照パラメーターを使用することを検討してください。渡した変数は、そのエイリアスが割り当てられたときに割り当てられます。

これを 2つの状況でよりよく理解しましょう。

オブジェクト自体を変更して別の場所またはオブジェクトを指す場合、変更は反映されません。別の場所への参照を指定した場合、変更は main() 関数に反映されません。

以下のコードを参照してください。

class Object {
  int x;
  Object(int z) {
    x = z;
  }
  Object() {
    x = 0;
  }
}

class Main {
  public static void main(String[] args) {
    // a reference
    Object O = new Object(7);

    // Reference passed and copy created in change()
    change(O);

    // old value
    System.out.println(O.x);
  }
  public static void change(Object O) {
    // reference changed to some other location any changes not reflected
    O = new Object();

    O.x = 8;
  }
}

出力:

7

ここで、新しい場所またはオブジェクトへの参照を割り当てないとします。その場合、結果はミラーリングされます。メンバーに変更を加えることができます。これらの変更は、別のオブジェクト(またはメモリ位置)を参照するように参照を変更しない場合に反映されます。

例えば、

class Object {
  int x;
  Object(int z) {
    x = z;
  }
  Object() {
    x = 0;
  }
}

class Main {
  public static void main(String[] args) {
    // a reference
    Object O = new Object(7);

    // Reference passed and copy created in change()
    change(O);

    // old value
    System.out.println(O.x);
  }
  public static void change(Object O) {
    O.x = 8;
  }
}

出力:

8