損した気分

前にC#ネタでジェネリクスの型パラメタだけが違うクローズ型のスタティックフィールドは共有されるのかという内容のエントリを書いたが、Javaでは期待通りの結果にならないので注意が必要だ。

前回のエントリのサンプルコードをJava用に書き換えてみる。

public class Foo {
    static String staticField = "static field";
    static {
        System.out.println("called static constructor.");
        System.out.println( staticField );
        staticField = null;
    }
    public Foo() {}
    public class Bar {}
    public class Baz {}

    public static void main(String[] args)  {
        Foo barFoo = new Foo();
        Foo bazFoo = new Foo();
    }
}

実行結果

called static constructor.
static field

実行結果を見れば判るが、Javaの場合、スタティック・コンストラクタは一度しか動かない。Foo型とFoo型は内部的には区別されていないことが判るだろう。
Javaでは型パラメタの違うジェネリクス型は違う型とは認識されないために、こうなるのが当たり前なのだがこれだと残念ながら真のジェネリクスとはいえない。

という訳で同じ型としてみなされるジェネリクス型、以下はコンパイルが通らない。

public class Foo {
    static T staticField; //型パラメタをstaticフィールドに指定できない
}

この手が使えないのは凄くがっかりだ。