参照渡し


配列、オブジェクトを渡す

メソッドへパラメータを渡すとき、メソッド側が受け取るのは渡された値のコピーです
変数のスコープによって、メソッドから別のメソッドの変数を操作することはできません
渡されたパラメータが変数でも、メソッドから呼び出しもとの変数値の変更はできないのです

このパラメータの渡し方を値渡しと呼びます
値渡しでは、呼び出しもとのローカル変数は一切操作できません
class test {
	String name;
	int age;

	public static void main(String args[]) {
		test hina = new test();
		hina.name = "成瀬川なる";
		hina.age = 17;
		System.out.println("名前\t\t年齢");
		hina.write();

		prm_ch(hina.name , hina.age);
		hina.write();
		
	}

	void write() {
		System.out.println(name + "\t" + age);
	}

	static void prm_ch(String name , int age) {
		name = "前原しのぶ";
		age = 13;
		System.out.println(name + "\t" + age + "(prm_chメソッド内)");
	}
}
prm_ch()メソッドに、main()メソッドから値を渡しています
hinaオブジェクトの各値を渡し、prm_ch()メソッドで受け取ったパラメータの値を更新しています
その値は、当然同じメソッド内であれば何の問題もなく変更されています
しかし、main()メソッドのhinaオブジェクトの値は何も変化していません
当然の結果ですね。prm_chに渡されていたのはhinaオブジェクトの各値のコピーでしかないのです
結果は次のようになります
名前            年齢
成瀬川なる      17
前原しのぶ      13(prm_chメソッド内)
成瀬川なる      17
main()メソッドのhinaオブジェクトには何の変化もないことがわかります

C/C++言語では、これにおいて参照渡しという技術がサポートされています
C言語はポインタが、C++には参照がサポートされているので、メモリアドレスを渡すことができるのです

しかし、JAVA言語にはポインタのようなものは存在しません
そのかわり、JAVA言語は配列、及びオブジェクトは参照渡しなのです
これは、プログラマが指定するのではなく、JAVA自体がそのような仕様になっています
つまり、配列やオブジェクトの場合は値ではなくメモリアドレスが値で渡されるのです
class test {
	String name;
	int age;

	public static void main(String args[]) {
		test hina = new test();
		hina.name = "成瀬川なる";
		hina.age = 17;
		System.out.println("名前\t\t年齢");
		hina.write();

		ref(hina , "前原しのぶ" , 13);
		hina.write();
		
	}

	void write() {
		System.out.println(name + "\t" + age);
	}

	static void ref(test obj , String name , int age) {
		obj.name = name;
		obj.age = age;
	}
}
オブジェクトは型が同じであれば、メンバごと渡すことができます
C言語の関数間の構造体の受け渡しに類似しています

ref()メソッドは test クラスのオブジェクトを第一パラメータで受け取ります
ここで受け取るのはコピーではなく、オブジェクトへのアドレスです
この参照を利用することによって、main()メソッドのオブジェクトのメンバの内容を変更することができます
配列においても、これと同じように参照が渡されるので、呼び出しもとの配列の内容が変化します
結果は次のようになりました
名前            年齢
成瀬川なる      17
前原しのぶ      13
オブジェクトのメンバ変数が、指示どおりに変化していることがわかりますね


これは、戻り値に関してもおなじことであり
実用的プログラムにおいては、インスタンスの生成は必ずしもnewとは限らないのです
たとえば、あるクラスのインスタンスを生成するには、あるメソッドを実行し
そのメソッドが目的のインスタンスを正確に生成して、その参照を返すという場面があります
class test {
	public static void main(String args[]) {
		
		Kitty obj = getKitty();
		obj.write();
	}
	static Kitty getKitty() {
		return new Kitty();
	}
}

class Kitty {
	void write() {
		System.out.println("Kitty on your lap");
	}
}
testクラスの静的メンバ getKitty() メソッドは戻り値で Kitty 型を指定しています
これは、Kitty型の参照を返すということです



前のページへ戻る次のページへ