Okapi Project

参照データ型で初心者が陥る問題

バージョン
2004 年 04 月 05 日 Ver.1.0
作成者
K.Takimoto ( Xware )

要約

参照データ型は、変数に実態を持たないため、代入では参照値が引き渡されます。これを十分理解していないと思わぬトラブルに巻き込まれます。

この資料では、参照型での代入の仕組みと注意点を見てみましょう。

目次


1. 基本データ型と参照データ型

基本データ型と参照データ型についておさらいしてみましょう。

基本データ型は変数自体にデータの値を保持していますが、参照データ型の変数には、データの値ではなく、データのある場所を保持しています。この、データのある場所のことを参照値といいます。

2. 参照型の代入

前記したように、参照データ型の変数は、値の実態が格納されている場所を持ちます。

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

実は、ここに初心者が陥りやすい問題が隠れています。

上記のように代入された場合でも、実態は一つなので、どちらか一方の値を変更したつもりでが、もう一方の変数の値も変更されるといった事態になります。

3. 簡単例で実験してみよう

3.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

3.2. 参照データ型で確認

前のコードは、「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 リファレンス )


Copyright © 2003 - 2006 Okapi Project All Rights Reserved.