Variance in Java

JDK 5.0においてはparametric polymorphism (aka generics)が採用され,型変数を使って定義したクラス CC とか書くことでインスタンシエートできる(型の消去に基づく).ここで元々のinclusion polymorphism (aka subtyping)との関連がかなり複雑になっているようだ.

型変数を使って定義したクラス定義一つから,(τをメタな型変数として) C<τ> と書くとinvariant, C<? extends τ> と書くとcovariant, C<? super τ> と書くとcontravariantな型が得られる... と書こうと思ったんだが,そもそも C<? extends τ> の存在意義は σ <: τ なる型に対し C<σ> <: C<? extends τ> となることである.こういうのを何て呼ぶんだろう?
The Java Programming Language の著者Ken Arnoldの意見は「Genericsなんて複雑な割にご利益が少ない.採用すべきでなかった.みんな今までgenericsなしでやってきたじゃん」だそうな.

私はコンテナが使いやすくなったことだけでもgenericsいいと思うけどね.

    ArrayList<? super Number> ausn;
    ArrayList<? extends Number> auen;
    ArrayList<Object> ao = new ArrayList<Object>();
    ArrayList<Number> an = new ArrayList<Number>();
    ArrayList<Integer> ai = new ArrayList<Integer>();
    ausn = ao;
    ausn = an;
    // ausn = ai; // invalid
    // auen = ao; // invalid
    auen = an;
    auen = ai;
    // co/contra-variance
    ArrayList<? super Object> auso = null; // array of unknown which is superclass of Object
    ArrayList<? extends Object> aueo = null;
    ArrayList<? super Integer> ausi = null;
    ArrayList<? extends Integer> auei = null;

    // contravariance!
    ausi = auso;
    // auso = ausi; // invalid

    // covariance!
    // auei = aueo; // invalid
    aueo = auei; 

><