Javaの「参照による値渡し」という概念

こんにちは。ゆうせいです。

Javaでプログラムを書き始めると、「参照による値渡し」という概念に出会うことがあると思います。この用語、最初は少しややこしいかもしれませんが、実際に仕組みを理解すれば、Javaがデータをどのように扱っているのかをしっかり理解できます。

今回は、「参照による値渡し」とは何か、そしてそれがJavaでどのように働いているかを詳しく解説します。


1. 参照による値渡しとは?

まず、「参照による値渡し」という言葉を一度整理してみましょう。

値渡し(pass by value)とは、メソッドに引数を渡す際、元のデータのコピーを渡す方式のことです。対して、参照渡し(pass by reference)とは、データそのものではなくデータがある場所(参照)を渡す方式のことです。

Javaは「参照による値渡し」

Javaではすべてのデータが「値渡し」でメソッドに引き渡されますが、オブジェクト型(配列やクラスのインスタンス)の場合、その「値」が参照(reference)であるため、元のオブジェクトの内容に変化を加えられることがあります。このため、Javaは「参照による値渡し」と言われることが多いのです。


2. 実際の挙動:基本型とオブジェクト型での違い

Javaのメソッドで引数を渡す際の挙動を理解するために、基本型とオブジェクト型での動きを比べてみましょう。

基本型の値渡し

Javaの基本型(intdoubleなど)は、実際のデータのコピーが渡されます。以下の例で考えてみましょう。

public class Main {
    public static void main(String[] args) {
        int a = 10;
        modifyValue(a);
        System.out.println(a); // 結果: 10
    }

    public static void modifyValue(int x) {
        x = 20;
    }
}

この例では、modifyValueメソッドにaのコピーが渡されます。メソッド内でx = 20;と変更しても、a自体には影響がないため、メインメソッドでaを出力しても10のままです。

オブジェクト型の参照による値渡し

一方、オブジェクト型のデータ(配列やクラスのインスタンス)は、参照が渡されます。そのため、元のオブジェクトの内容が変更される可能性があります。

以下の例を見てください。

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        modifyArray(arr);
        System.out.println(arr[0]); // 結果: 10
    }

    public static void modifyArray(int[] array) {
        array[0] = 10;
    }
}

この場合、arrの参照がmodifyArrayメソッドに渡されます。array[0] = 10;という変更は、元のarrに対して行われるため、メインメソッドでarr[0]を出力すると10に変わっているのです。


3. 参照を新しいインスタンスに置き換える場合

Javaでは、メソッド内で引数の参照先を新しいオブジェクトに置き換えることもできます。しかし、この場合もメソッド外には影響しません。これについても見ていきましょう。

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        replaceArray(arr);
        System.out.println(arr[0]); // 結果: 1
    }

    public static void replaceArray(int[] array) {
        array = new int[] {10, 20, 30}; // 新しい配列を参照
    }
}

replaceArrayメソッド内でarrayを新しい配列に置き換えても、メソッドを抜けた後は元のarrには影響を与えません。これは、arrayがメソッド内でローカル変数として新しい参照先を持つようになったためです。元のarrの参照には影響がないので、メインメソッドでarr[0]を出力すると、最初の1のままです。


4. なぜJavaは「参照による値渡し」と言われるのか?

Javaのオブジェクト型での渡し方を一言で表すなら、「参照を値として渡す」という表現が正確です。値渡しであることは基本型と同様ですが、その「値」がオブジェクトの参照であるため、参照先のオブジェクトに対して操作を行うことができるのです。


5. まとめ

  • Javaは値渡し:すべてのデータを「値渡し」で引き渡す。
  • 基本型ではコピーが渡され、元の値には影響がない。
  • オブジェクト型では参照が渡され、メソッド内で参照先のデータを変更すると元のオブジェクトにも影響を与える。
  • 新しい参照先を設定しても、外のオブジェクトには影響しない:参照自体はローカル変数として扱われるため。

Javaの「参照による値渡し」は少しややこしいですが、理解しておくとコードの動きがしっかり見えてきます。ぜひ、基本型とオブジェクト型の渡し方の違いを試して、Javaのメモリ管理の仕組みに慣れてみてくださいね!

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。