参照データ型は、変数に実態を持たないため、代入では参照値が引き渡されます。これを十分理解していないと思わぬトラブルに巻き込まれます。
この資料では、参照型での代入の仕組みと注意点を見てみましょう。
基本データ型と参照データ型についておさらいしてみましょう。
基本データ型は変数自体にデータの値を保持していますが、参照データ型の変数には、データの値ではなく、データのある場所を保持しています。この、データのある場所のことを参照値といいます。

前記したように、参照データ型の変数は、値の実態が格納されている場所を持ちます。
そこで、参照データ型の代入を想像してみてください。代入式 「 A = B ; 」は、B 変数の内容を A 変数に設定しますが、ここで B 変数 の何が A 変数に設定されるのでしょうか? 参照データ型の代入では、実態が代入されることは無く、実態の場所である、参照値が代入されます。つまり 「 A = B ; 」 を実行した後の B 変数と A 変数は、同じ参照値を持つことなり、1つの実態を両者が参照することになるわけです。

実は、ここに初心者が陥りやすい問題が隠れています。
上記のように代入された場合でも、実態は一つなので、どちらか一方の値を変更したつもりでが、もう一方の変数の値も変更されるといった事態になります。
次のコードは、「int型」の変数に 2 つ対して、一方の変数の値をもう一方の変数の値に代入した後、代入もとの変数の値を書き換えるという内容です。
public class test {
public static void main(String[] args) {
int i1 = 10;
int i2 = i1;
i1 = 20;
System.out.println("i1 = "+i1+" i2 = "+i2);
}
}
このコードの実行結果は次のように、変数の値はそれぞれ異なる値になります。当たり前といえば、当たり前のことですね。
i1 = 20 i2 = 10
前のコードは、「int型」の変数を使用しました。そこで、「int型」の変数を自分で作成した「数値を保持するクラス」に置き換えてみたいと思います。
まずは、数値を保持するクラス「Num」を作成します。このクラスでは、「int型」の値を保持します。
public class Num {
private int num;
public Num(int num){
this.num = num;
}
public void setNum(int num){
this.num = num;
}
public int getNum(){
return this.num;
}
}
それでは、基本データ型の実行例と同じように、作成したクラスを使用して同じことをしてみましょう。
public class test {
public static void main(String[] args) {
Num i1 = new Num(10);
Num i2 = i1;
i1.setNum(20);
System.out.println("i1 = "+i1.getNum()+" i2 = "+i2.getNum());
}
}
実行結果は以下のようになります。 代入先の変数である「i2」については、値を変更するコードは書いていないにもかかわらず、値が変化してしまうのがわかります。
i1 = 20 i2 = 20
データ型 ( Okapi 版 Java リファレンス )