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が指している同一のオブジェクトの値が変化しています。