たぷつきません

おなかがでてきた。もうたぷついてるやん。

外部から生成可能なインナークラス

 Eclipse JDT Pluginのソースをハックしていて初めて知ったのですが、なんとインナークラスなのに外部から直接生成したり、staticメンバを持たせることができる方法がありました。
 これをするには全然むずかしいことはなく、ただ単にインナークラスの宣言にstaticを付加するだけです。public static にすれば、他のパッケージからも可視になります。

package test;

public class ClassA {
    public static class InnerA {
        // 実は普通のインナークラスにはstaticメソッドを
        // 作成することはできないのですが、staticインナークラス
        // の場合に限り、定義できちゃいます。
        public static void staticHello() {
            System.out.println("hello - static");
        }
        public void hello() {
            System.out.println("hello");
        }
    }
}
package test.hoge;

import test.ClassA.InnerA;   // こんな宣言もできちゃうのですよー。

public class ClassB {
    public static void main(String[] args) {
        
        // staticメソッド呼び出し例
        InnerA.staticHello();
        
        // 普通のインナークラスでは
        // インスタンスの直接生成はできません。
        InnerA directInstance = new InnerA();
        directInstance.hello();
    }
}

 たしかに「staticなし」メンバは、インスタンスを伴うのが当然なので妙に納得してしまいました。
 更に static が付いている限り、インナーのネストができてしまいます。

package test;

public class ClassA {
    public static class InnerA {
        public static class MoreInnerA {
            public static class DeepA {
                public static void staticHello() {
                    System.out.println("深すぎ!");
                }
            }
        }
    }
}
package test.hoge;

import test.ClassA.InnerA.MoreInnerA.DeepA;

public class ClassB {
    public static void main(String[] args) {
        DeepA.staticHello();
    }
}

 importが示すのがパッケージなのかインナークラスのネストなのか、もう何がなにやら分からなくなるので多用しないほうが吉です。でもあまり使われないせいか、Eclipse2.1でも3.0でも、インナークラスのimportの定義から「宣言を開く」を行うとうまくいかず、おもしろいことに、ビルドパスに同名クラスがあると、その全く関係ないクラスを開いちゃうようです。


コメント
かとちん(2005/01/25 11:15)
まさたかさんからJava魂にも載っていることを聞きました。