参照型とオブジェクト

参照型とオブジェクト

これまでの解説で、配列型の変数(配列変数)は配列本体を指す変数だということがよくお分かりいただけたのではないでしょうか。

new演算子で生成されるデータの実体はオブジェクト(object)と呼ばれます。 従って、配列本体はオブジェクトです。 そして、オブジェクトを指す変数の型を参照型(reference type)と呼びます。 配列変数は参照型の変数ということになります。

後ほど解説するクラス型インスタンスの関係も、配列型と配列本体の関係によく似ています。 つまり、インスタンスはオブジェクトで、クラス型の変数はインスタンスを指す参照型の変数なのです。

図 8-10 : 参照型とオブジェクト

空リテラルと空参照

参照型の変数がオブジェクトを参照していない状態を表すnullというリテラルが有ります。 このリテラルのことを空リテラル(null literal)と呼びます。 nullはどんな参照型の変数にも代入できる特別なリテラルです。 参照型の変数にnullを代入すると、この変数はどのオブジェクトも参照しなくなります。 このとき、この参照型の変数は空参照(null reference)であると言います。

例えば、配列変数にnullを代入すると、この配列変数はどの配列本体も参照しなくなります。

参照型の変数にnullを代入すると、その変数は何も参照しない空参照となる。

では、実際に配列変数にnullを代入するサンプルプログラムを見てみましょう。

ArraySample07.java
class ArraySample07 {
    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5};
        System.out.println("a = " + a);

        a = null;    //nullを代入することにより、配列変数aは空参照となる。
        System.out.println("a = " + a);
    }
}
ArraySample07の実行結果
a = [I@bf216a
a = null

ArraySample07では、配列aを初期化してから、配列の要素ではなく、配列変数そのものを表示します。

        int[] a = {1, 2, 3, 4, 5};
        System.out.println("a = " + a);

この結果「[I@bf216a」という値が表示されていますが、これは特に役に立つものではありません。

次に配列変数aにnullを代入して、aを空参照としています。

        a = null;    //nullを代入することにより、配列変数aは空参照となる。
        System.out.println("a = " + a);

aが空参照の場合、その値は「null」と表示されることが分かります。

空参照となっている変数を出力すると、「null」と表示される。

ガーベジコレクション

さて、nullを代入されることによって、配列変数は空参照になるのですが、参照されなくなった配列本体はどうなるのでしょうか。 もしも、この配列本体を参照している配列変数が他に無ければ、最早この配列本体はプログラムからアクセスすることはできません。 言わばメモリ上のゴミとなってしまうのです。 プログラムの実行中にこういったゴミが増えてくると、メモリの無駄遣いになるばかりか、実行速度まで落ちてきてしまいます。

そこで、Javaには、こういったゴミを自動的に回収してくれるガーベジコレクション(garbage collection)という機能が備えられています。 ガーベジコレクションは、不要となったオブジェクトの領域を自動的に解放して、再び使えるようにしてくれる大変有り難い機能なのです。

英語のgarbage collectionとは、まさに「ゴミ収集」という意味です。

図 8-11 : 空参照とガーベジコレクション

オブジェクトが参照されなくなるのは、配列変数にnullを代入したときだけではありません。 ArraySample05とArraySample06を思い出してください。 配列変数bに他の配列本体への参照を代入した場合、それまでにbが参照していた配列本体はbによって参照されなくなります。 もしも、この配列本体がb以外の配列変数によって参照されていないならば、やはり、この配列本体はアクセス不能となり、ガーベジコレクションによって回収されることになります。

図 8-12 : 他の配列本体への参照の代入とガーベジコレクション