有以下课程:
public class LivingBeing { … }
然后就是
public class Human extends LivingBeing { … }
现在还有这个包装器:
public class LivingBeingWrapper<T extends LivingBeing> { … }
要完成图片,还有方法
public boolean validate(LivingBeingWrapper<LivingBeing> livingBeingWrapper)
现在编写以下代码
LivingBeingWrapper<Human> wrapper = createHumanWrapper();
validate(wrapper);
我收到以下编译错误:
方法验证(LivingBeingWrappe&lt; LivingBeing&gt; liveBeingWrapper)在MyType类型中不适用于 参数(LivingBeingWrapper&lt; Human&gt;)。
但为什么呢? Human
扩展了LivingBeing
。
答案 0 :(得分:6)
香蕉是一个水果。但是香蕉列表不是水果列表。否则你可以拿一份香蕉并添加一个苹果(假设一个苹果是一个水果)。
听起来相当古怪,但它是上面发生的事情的关键。您需要指定包装器,使其类型扩展为LivingBeing
。
有关详细信息,请参阅this article,特别是“Generics not covariant”部分。
答案 1 :(得分:3)
您的validate
方法声明必须使用LivingBeingWrapper
LivingBeing
参数调用它。但是,您传递的LivingBeingWrapper
参数设置为Human
。尝试更改方法声明:
public boolean validate(LivingBeingWrapper<LivingBeing> livingBeingWrapper)
到此:
public boolean validate(LivingBeingWrapper<? extends LivingBeing> livingBeingWrapper)
答案 2 :(得分:1)
更改以下方法: -
public boolean validate(LivingBeingWrapper<LivingBeing> livingBeingWrapper)
到
public boolean validate(LivingBeingWrapper<T> livingBeingWrapper)
由于此方法位于您的类中,如: -
public class LivingBeingWrapper<T extends LivingBeing>
因此,您可以在方法参数中使用类型T,并且T将替换为Horse
..以供您特定参考..
如果您的方法采用与class definition (T)
不同的类型,那么您可以使用此声明: -
public boolean validate(LivingBeingWrapper<? extends LivingBeing>
livingBeingWrapper)
现在,如果您必须调用 validate(LivingBeingWrapper<Human>)
,则必须定义您的方法以采用泛型类型参数类型Human
,该类型扩展LivingBeing
,是你的T
类型(因为它还在你的类定义中扩展了LivingBeing)