S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

java.lang.Class型の変数にジェネリックスで型を指定しなければならない理由

java.lang.Class型の変数に格納された、ClassオブジェクトのnewInstance()メソッドで生成されるオブジェクトに対する、タイプセーフが目的らしい。
J2SE 5.0の新機能――第1回 型の安全性を確保する新文法「Generics」 - ITアーキテクト [IT Architect]
スーパークラスとかインターフェースならOKじゃねぇんか?と思って試してみたけど、今度はコンパイルエラーが出る始末。


一応一通りの組み合わせで確認してみた。

public class X {
    private interface A{
    }
    private class AA extends X implements A {
    }
    private Class<AA> class_AA_AA = AA.class;   // OK 
//  private Class<AA> class_AA_X = X.class;     // NG
//  private Class<X> class_X_AA = AA.class;     // NG
    private Class<X> class_X_X = X.class;       // OK
//  private Class<A> class_A_AA = AA.class;     // NG
    private Class<A> class_A_A = A.class;       // OK
//  private Class<AA> class_AA_A = A.class;     // NG
}

【追記:2010/07/23】<? extends T>とか<? super T>とか

id:wamanさんのコメントを確認してみた。
ついでに<? super T>という記述もOKみたいなので。

    private Class<? extends A> class_ex_A_AA = AA.class;
    private Class<? extends A> class_ex_A_A = A.class;
    private Class<? extends X> class_ex_X_AA = AA.class;
    private Class<? extends X> class_ex_X_X = X.class;
    private Class<? super AA> class_sp_AA_X = X.class;
    private Class<? super AA> class_sp_AA_A = A.class;
    private Class<? super AA> class_sp_AA_AA = AA.class;

<? extends T>は、newInstance()メソッドで生成されるオブジェクトのタイプセーフという意味で判るけど、<? super T>はどんなときに使うんだろ???


Java総称型メモ(Hishidama's Java Generics Memo) > 不定を意味する型引数(ワイルドカード)
型の
extends=上限境界ワイルドカード(upper bounded wildcard)
super=下限境界ワイルドカード(lower bounded wildcard)
という意味で、superでObject型まで行くと結局なんでもOKになっちゃうね。ということらしい。