用泛型编译错误

时间:2012-10-03 08:28:05

标签: java generics inheritance compiler-errors extends

有以下课程:

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

3 个答案:

答案 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)