日々常々

ふつうのプログラマがあたりまえにしたいこと。

Groovyでネストしたクラスを触る時に注意しないといけないかもしれないこと

結論は「よくわかりません!」なのでメモ代わりです。


とりあえずバージョン

PS> groovy -version
Groovy Version: 1.8.0 JVM: 1.6.0_24

本題

class Outer {
    static class Inner {
    }
}
class Child extends Outer{
}

new Child.Inner();

Javaだと出来る「子クラス経由で親クラスが持つstaticのネストしたクラスのインスタンス生成」だけど、Groovyだとダメらしい。なんか見えないっぽい。コンパイルエラーの意味わからなくて暫く悩んでしまった…。

class Outer {
    static def o = new Object()
}
class Child extends Outer{
}

assert Outer.o == Child.o

とりあえず「継承したstaticがダメ」なわけじゃないのは確認…。

http://jira.codehaus.org/secure/IssueNavigator.jspa は検索してみたけれど、それっぽいのは見つけられなかったので、また今度見直したいと思います。

脱線

試行錯誤してるうちに 内部クラスはエンクロージングインスタンスが無くてもインスタンス化できる? - 裏紙 に近いネタまで遡ってしまったり。

public class Main {
    public static void main(String[] args) {
        new Outer().new Inner();
    }
}

class Outer {
    class Inner {
    }
}

これがJavaだと特に問題ないんだけど、Groovyだとエラーになっちゃう。

Caught: groovy.lang.MissingMethodException: No signature of method: static Main.Inner() is applicable for argument types: () values: []
Possible solutions: inject(java.lang.Object, groovy.lang.Closure), any(), every(), any(groovy.lang.Closure), every(groovy.lang.Closure), find(groovy.lang.Closure)
        at Main.main(Main.groovy:3)

Main.Inner()?なんか別のもの探してるような……。


エラーログ見てたら内部クラスのnewInstanceはパラメータが要った事*1を思い出した。

public class Main {
    public static void main(String[] args) {
        new Outer.Inner(new Outer());
    }
}

class Outer {
    class Inner {
    }
}

出来た!勿論Javaでは動きません。

      • -

7/14 20:01 修正

  • 「staticな内部クラス」とか書いてたので直し。
    • staticでないネストしたクラスを内部クラスと呼ぶ。*2
    • 内部クラスはネストしたクラスだけど、ネストしたクラスは内部クラスじゃない。

*1:リフレクションでprivateをテストしてみる - 日々常々 とかでやってます。

*2:プログラミング言語Java 第4版 5.2 内部クラス」参照