Java メソッドの参照の値渡し

Javaのメソッドで引数にオブジェクトを渡した際の挙動が慣れるまでは分かりずらい点があるため、整理します。

目次

メソッドの引数に変数を渡したときの挙動

変数の型渡されるもの
プリミティブ型値のコピー
オブジェクト型参照の値のコピー

Javaのオブジェクト型の変数はその値として、オブジェクトのアドレスの値を持ちます。これは以下のような値です。

@28a418fc

サンプルコード

ReferenceSampleクラス


package refrence;

public class ReferenceSample {
    public static void main(String[] args) {
        Animal animal1 = new Animal("Kenji");
        ReferenceSample.print("main", "animal1", animal1); // Kenji
        method1(animal1);
        ReferenceSample.print("main","animal1", animal1); // Kenji
        method2(animal1);
        ReferenceSample.print("main","animal1", animal1);
    }

    public static void method1(Animal animal3) {
        ReferenceSample.print("method1", "animal3", animal3); // Kenji
        Animal animal2 = new Animal("Hanako");
        ReferenceSample.print("method1", "animal2", animal2); // Hanako
        animal3 = animal2;
        ReferenceSample.print("method1", "animal3", animal3); // Hanako
    }
    public static void method2(Animal animal4) {
        ReferenceSample.print("method2", "animal3", animal4); // Hanako
        animal4.setName("Taro");
        ReferenceSample.print("method2", "animal4", animal4); // Hanako
    }

    public static void print(String method, String variableName, Animal animal) {
        System.out.printf("%s: %s: %s %s%n", method, variableName, animal, animal.getName());
    }
}

Animalクラス

package refrence;

public class Animal {

    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

ReferenceSampleのmainメソッドを呼び出すと、以下のような結果になります。

main: animal1: refrence.Animal@28a418fc Kenji
method1: animal3: refrence.Animal@28a418fc Kenji
method1: animal2: refrence.Animal@5305068a Hanako
method1: animal3: refrence.Animal@5305068a Hanako
main: animal1: refrence.Animal@28a418fc Kenji
method2: animal3: refrence.Animal@28a418fc Kenji
method2: animal4: refrence.Animal@28a418fc Taro
main: animal1: refrence.Animal@28a418fc Taro

挙動の図解による説明

Method1が呼び出されたとき

mainからmethod1を呼び出す時に変数animal1を渡しています。method1のローカル変数に何を代入したところで、method1のローカル変数のスコープを抜ければ(method1が終了すれば)変数は消滅します。method1の中で変数に値を代入することは、呼び出し元の変数の中身に影響を与えないことが分かります。

Method2が呼び出されたとき

method2の中ではローカル変数であるanimal4に対してメソッドを呼び出します。これはanimal4が指しているオブジェクトに対して変更を与えます。そのため、main関数に戻った際にanimal1、animal4が指している同一のオブジェクトの値が変化しています。

よかったらシェアしてね!
目次