クラスの内部のクラス innerクラス


 JDK1.1のリリースと同時に Javaの言語仕様の一部が拡張されました。 一番大きな追加が innerクラスと呼ばれるものです。 これはクラス定義の内部にさらにクラス定義を記述できるというものです。 たとえば次のようになります。


/** 内部に子供のクラスの定義を持つクラス */
public class Father {

   /** 子供のクラスの定義 */
     class Child {
            public String name;
            public int age;
     }

   /** 上で定義した子供のクラスの配列 */
     private Child children[];
}

上の例ではクラスFather の中にさらにクラスChild が定義されています。 このような階層関係は多重になってもかまいません。 innerクラスの内部にさらに innerクラスを定義することもできるわけです。 innerクラスを用いると、 専用の部品の記述が手軽にできるなどプログラミングの柔軟度が高まります。
 ところで上のソースをコンパイルすると、 どんなバイトコードが生成されるのでしょうか? innerクラスのバイトコードも独立したファイルとなります。 ただし、どのクラスの内部で定義されたものなのかがファイル名に反映されます。 クラスの階層関係は "$" を区切り文字として表されます。 上の例では Father.class の他に Father$Child.class という名前の バイトコードが生成されることになります。

 innerクラスは必要になったその場所で、 その場限りの利用をするというケースが多いでしょう。 そのため、クラス定義とオブジェクトの生成を同時に行えるようになっています。 また、その時にクラスの名前を付けるのを省略してしまうことすらあります。


/** 内部に子供のクラスの定義を持つクラス */
public class Mother {

   /** 最初に呼び出されるメソッド */
     public static void main( String argv[] ) {

       /* Objectクラスをスーパークラスとする新しいクラスの定義と
          そのオブジェクトの生成を同時に行う。クラス名は省略 */
          Object child
           = new Object(){
                     public String name="";
                     public int age=0;
           };
     }
}

 上のソースをコンパイルすると、 innerクラスのバイトコードのファイル名はどうなるのでしょうか?  この場合はクラス名が存在しないので、 本来クラス名が入るべきところは適当な数字を使って区別します。 上の例では Mother.class の他に Mother$1.class という名前のバイトコードが生成されます。