【问题标题】:Compile error with generics使用泛型编译错误
【发布时间】:2012-10-03 08:28:04
【问题描述】:

有以下类:

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);

我得到以下编译错误:

方法 validate(LivingBeingWrappe livingBeingWrapper) 类型的 MyType 不适用于 参数(LivingBeingWrapper)。

但是为什么呢? Human 扩展 LivingBeing

【问题讨论】:

  • &lt;LivingBeing&gt; 表示只有 LivingBeing,&lt;? extends LivingBeing&gt; 表示它可以扩展 LivingBeing。例如人类。
  • 我认为您正在遭受类型擦除...不过,对于结构良好的问题 +1
  • 你可以试试:public boolean validate(LivingBeingWrapper&lt;? extends LivingBeing&gt; livingBeingWrapper)

标签: java generics inheritance compiler-errors extends


【解决方案1】:

香蕉是一种水果。但是香蕉列表不是水果列表。否则,您可以列出香蕉并添加一个苹果(假设苹果 is-a 水果)。

这听上去很玄妙,但它是上面发生的事情的关键。您需要指定包装器,使其采用扩展 LivingBeing 的类型。

有关详细信息,请参阅this article,尤其是“泛型不是协变的”部分。

【讨论】:

  • 我喜欢这个解释。如果您也添加具体建议,我将删除我的答案。
【解决方案2】:

您的validate 方法声明必须使用LivingBeingWrapper 参数化LivingBeing 来调用它。但是,您传入的是使用Human 参数化的LivingBeingWrapper。尝试从此更改您的方法声明:

public boolean validate(LivingBeingWrapper<LivingBeing> livingBeingWrapper)

到这里:

public boolean validate(LivingBeingWrapper<? extends LivingBeing> livingBeingWrapper)

【讨论】:

    【解决方案3】:

    更改您的以下方法:-

    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&lt;Human&gt;),您的方法必须定义为采用泛型类型参数类型Human,它扩展了LivingBeing,这就是您的T类型是(因为它还在你的类定义中扩展了 LivingBeing)

    【讨论】:

    • validate 不是 LivingBeingWrapper 上的方法。
    • 您使用的是T。但validate 不一定是参数化类的方法。
    • @DavidGrant.. 是的,我认为它在那个类里面.. 所以,我已经提到了.. 编辑帖子以添加该部分..
    猜你喜欢
    • 2012-04-21
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    相关资源
    最近更新 更多