内部是这样的,它是的子类可以在其范围内<? super T>
。<T extends Juicy<? super T>>
RedOrange
Juicy<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
上面的调用编译。
编辑
但是如果我们想从squeeze
a中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);