参照の複製
質問:「参照型変数A = 参照型変数B」ってしたらどうなるの?
解答:参照がコピーされます。
インスタンスの説明をした時に「インスタンスには参照がくっついている」と説明しました。
実は、この参照、増えます。参照はコピーできるので、1つのインスタンスを複数の参照から操作することができます。
// RefCopyRunner.java
/**
* フィールド1つだけ持つシンプルなクラス。
* (SimpleClassと同じものです)
*/
class SimpleClass3
{
// int型変数のフィールドdataを定義します。
int data;
}
/**
* 実行用クラス。このクラスを実行してください。
*/
class RefCopyRunner
{
public static void main( String[] args )
{
// SimpleClass3クラスの参照型変数とインスタンスを作ります。
SimpleClass3 ref = new SimpleClass3();
// SimpleClass3クラスの参照型変数をもう1つ作ります。
SimpleClass3 ref2;
// このref2変数に、ref変数に入っている参照をコピーします。
ref2 = ref;
// そうすると、ref変数とref2変数の両方から1つのインスタンスを
// 参照する形になります。
ref.data = 100;
System.out.println( ref2.data );
// 出力結果:
// 100
// ref.dataとref2.dataは同じインスタンスのdataフィールドなので
// このような結果になるわけです。
}
}
/**
* フィールド1つだけ持つシンプルなクラス。
* (SimpleClassと同じものです)
*/
class SimpleClass3
{
// int型変数のフィールドdataを定義します。
int data;
}
/**
* 実行用クラス。このクラスを実行してください。
*/
class RefCopyRunner
{
public static void main( String[] args )
{
// SimpleClass3クラスの参照型変数とインスタンスを作ります。
SimpleClass3 ref = new SimpleClass3();
// SimpleClass3クラスの参照型変数をもう1つ作ります。
SimpleClass3 ref2;
// このref2変数に、ref変数に入っている参照をコピーします。
ref2 = ref;
// そうすると、ref変数とref2変数の両方から1つのインスタンスを
// 参照する形になります。
ref.data = 100;
System.out.println( ref2.data );
// 出力結果:
// 100
// ref.dataとref2.dataは同じインスタンスのdataフィールドなので
// このような結果になるわけです。
}
}
// RefCopyRunner.java /** * フィールド1つだけ持つシンプルなクラス。 * (SimpleClassと同じものです) */ class SimpleClass3 { // int型変数のフィールドdataを定義します。 int data; } /** * 実行用クラス。このクラスを実行してください。 */ class RefCopyRunner { public static void main( String[] args ) { // SimpleClass3クラスの参照型変数とインスタンスを作ります。 SimpleClass3 ref = new SimpleClass3(); // SimpleClass3クラスの参照型変数をもう1つ作ります。 SimpleClass3 ref2; // このref2変数に、ref変数に入っている参照をコピーします。 ref2 = ref; // そうすると、ref変数とref2変数の両方から1つのインスタンスを // 参照する形になります。 ref.data = 100; System.out.println( ref2.data ); // 出力結果: // 100 // ref.dataとref2.dataは同じインスタンスのdataフィールドなので // このような結果になるわけです。 } }
このプログラムでは、SimpleClass3クラスのインスタンスを作った際に、そのインスタンスへの参照をref変数に入れて、さらにそれをref2変数にコピーしています。
// SimpleClass3クラスの参照型変数とインスタンスを作ります。
SimpleClass3 ref = new SimpleClass3();
// SimpleClass3クラスの参照型変数をもう1つ作ります。
SimpleClass3 ref2;
// このref2変数に、ref変数に入っている参照をコピーします。
ref2 = ref;
SimpleClass3 ref = new SimpleClass3();
// SimpleClass3クラスの参照型変数をもう1つ作ります。
SimpleClass3 ref2;
// このref2変数に、ref変数に入っている参照をコピーします。
ref2 = ref;
// SimpleClass3クラスの参照型変数とインスタンスを作ります。 SimpleClass3 ref = new SimpleClass3(); // SimpleClass3クラスの参照型変数をもう1つ作ります。 SimpleClass3 ref2; // このref2変数に、ref変数に入っている参照をコピーします。 ref2 = ref;
こうすると、ref変数とref2変数の両方がインスタンスへの参照を持ちます。
このように、参照はコピーして増やせるので、複数の参照型変数から1つのインスタンスを操作することができます。
まずref変数を通してインスタンスのdataフィールドに「100」を入れます。
次にref2変数を通してインスタンスのdataフィールドから値を取り出しprintln()メソッドに渡しています。
// そうすると、ref変数とref2変数の両方から1つのインスタンスを
// 参照する形になります。
ref.data = 100;
System.out.println( ref2.data );
// 出力結果:
// 100
// ref.dataとref2.dataは同じインスタンスのdataフィールドなので
// このような結果になるわけです。
// 参照する形になります。
ref.data = 100;
System.out.println( ref2.data );
// 出力結果:
// 100
// ref.dataとref2.dataは同じインスタンスのdataフィールドなので
// このような結果になるわけです。
// そうすると、ref変数とref2変数の両方から1つのインスタンスを // 参照する形になります。 ref.data = 100; System.out.println( ref2.data ); // 出力結果: // 100 // ref.dataとref2.dataは同じインスタンスのdataフィールドなので // このような結果になるわけです。
どちらも同じインスタンスを操作しているので、このような結果になります。
実際には、複数の参照型変数から1つのインスタンスを操作しても、メリットはあまりありません。
むしろ、思っていたのと違うインスタンスを操作してしまったりする原因になりかねないので、ひとつのインスタンスを複数の参照型変数から参照するのはあまりしない方がいいでしょう。