上限境界を持つジェネリック型の実型パラメータに下限境界のワイルドカードを指定したとき

下のエントリにつづいてもう1つジェネリクスねた。

上限境界と下限境界を持つワイルドカードはおもしろいなぁと思いました。
? super を使ってパラメータ化された型はObjectしか返せないと思っていたのですが、その型の上限があらかじめ決まっているならその型で戻せるんですね(下のサンプルコードで言えばBクラスとして戻せるということ)。

public class BoundsTest {
    @Test
    public void testBounded() throws Exception {
        BoundedHolder<? super C> holder = new BoundedHolder<C>();
        holder.value = new D();
        B b = holder.value; // OK これがおもしろい
    }

    @Test
    public void testNotBounded() throws Exception {
        NotBoundedHolder<? super C> holder = new NotBoundedHolder<C>();
        holder.value = new D();
        B b = holder.value; // コンパイルエラー。Objectとしてなら返せる。
    }

    static class BoundedHolder<T extends B> {
        T value;
    }

    static class NotBoundedHolder<T> {
        T value;
    }

    static class A {
    }

    static class B extends A {
    }

    static class C extends B {
    }

    static class D extends C {
    }
}

BoundedHolderがポイント。NotBoundedHolderはNotBoundedHolderと考えれば筋が通りますね。