内部是这样的,它是的子类可以在其范围内<? super T>。<T extends Juicy<? super T>>RedOrangeJuicy<Orange>
想象一下没有第<? super T>一个:
public <T extends Juicy<T>> List<Juice<T>> squeeze(List<T> fruits) {...
现在T必须是一个Juicy<T>. 类Orange是一个Juicy<T>,它是一个Juicy<Orange>。但类RedOrange不是Juicy<T>. 这不是Juicy<RedOrange>; 这是一个Juicy<Orange>。因此,当我们尝试调用时squeeze:
List<RedOrange> redOranges = new ArrayList<RedOrange>();
List<Juice<RedOrange>> juices = squeeze(redOranges);
我们得到以下编译器错误:
Inferred type 'RedOrange' for type parameter 'T' is not within its bound; should implement 'Juicy<RedOrange>'.
如果我们放置<? super T>, 则允许类型参数 forJuicy成为 的超类T。这允许RedOrange使用,因为它是Juicy<Orange>, 并且Orange是RedOrange.
public <T extends Juicy<? super T>> List<Juice<T>> squeeze(List<T> fruits) {...
现在对squeeze上面的调用编译。
编辑
但是如果我们想从squeezea中List<Juice<Orange>>得到 aList<RedOrange>怎么办?它有点棘手,但我找到了解决方案:
我们需要Orange在squeeze方法中匹配第二个类型参数:
public <S extends Juicy<S>, T extends Juicy<S>> List<Juice<S>> squeeze(List<T> fruits)
在这里,S代表Orange,以便我们可以返回List<Juice<Orange>>。现在我们可以说
List<RedOrange> redOranges = new ArrayList<RedOrange>();
List<Juice<Orange>> juices = squeeze(redOranges);