泛型编译错误

3

以下是一个类:

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

我遇到了以下编译错误:

类型MyType中的方法validate(LivingBeingWrappe<LivingBeing> livingBeingWrapper)对于参数(LivingBeingWrapper<Human>)不适用。

但是为什么呢?Human继承自LivingBeing


"<LivingBeing>" 表示仅为 LivingBeing,"<? extends LivingBeing>" 表示它可以扩展 LivingBeing。例如:人类。 - Peter Lawrey
我认为你正在遭受类型擦除的困扰……尽管如此,因为问题结构良好而给你点赞。 - Redandwhite
你能试试这个吗:public boolean validate(LivingBeingWrapper<? extends LivingBeing> livingBeingWrapper) - Redandwhite
3个回答

6
一根香蕉水果。但一串香蕉不是水果的串。否则,你可以拿一串香蕉加上一个苹果(因为一个苹果水果)。
这听起来有点晦涩,但这是上面发生的事情的关键。您需要指定包装器,使其接受扩展LivingBeing类型的类型。
更多信息,请参见此文章,特别是“泛型不是协变的”部分。

我喜欢这个解释。如果您还提供具体建议,我会删除我的答案。 - David Grant

3

您的validate方法声明必须使用LivingBeing参数化的LivingBeingWrapper调用。但是,您正在传递一个使用Human参数化的LivingBeingWrapper。尝试将方法声明更改为:

public boolean validate(LivingBeingWrapper<LivingBeing> livingBeingWrapper)

转换为:

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

1

请修改您的以下方法:

public boolean validate(LivingBeingWrapper<LivingBeing> livingBeingWrapper)

public boolean validate(LivingBeingWrapper<T> livingBeingWrapper)

由于这个方法在你的类内部,就像:

public class LivingBeingWrapper<T extends LivingBeing> 

因此,您可以在方法参数中使用类型T,而T将被替换为Horse。供您参考。

如果您的方法采用与类定义(T)中不同的类型,则可以使用以下声明:-

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

现在,如果您必须调用 validate(LivingBeingWrapper<Human>),则您的方法必须定义为接受泛型类型参数类型 Human,该类型扩展了 LivingBeing,这也是您类定义中的 T 类型(因为它还扩展了 LivingBeing)


“validate”不是“LivingBeingWrapper”的方法。 - David Grant
你正在使用 T。但是 validate 不一定是参数化类上的方法。 - David Grant
@DavidGrant.. 是的,我假设它在那个类里面.. 所以我已经提到了它.. 编辑帖子以添加那部分.. - Rohit Jain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接