Java 泛型类型错误:实例无法转换为自己的类型?
我收到来自以下代码段的编译器错误。错误发生在指示行:Java 泛型类型错误:实例无法转换为自己的类型?,java,generics,Java,Generics,我收到来自以下代码段的编译器错误。错误发生在指示行: static abstract class AbstractRoot<R extends Root<R>> implements Root<R> { private final Map<Grouping, Phrase> m_ph; AbstractSqlRoot() { this.m_ph = new HashMap<>(); } @Override
static abstract class AbstractRoot<R extends Root<R>> implements Root<R> {
private final Map<Grouping, Phrase> m_ph;
AbstractSqlRoot() { this.m_ph = new HashMap<>(); }
@Override public PhraseBuilder<R> phrase() {
PhraseBuilder<R> fr = (PhraseBuilder<R>) m_ph.get(Grouping.PHRASE);
if (fr == null) {
--> fr = new PhraseBuilder<R>(this);
m_ph.put(Grouping.PHRASE, fr);
}
return fr;
}
编译器报告“不兼容的类型:AbstractRoot
无法转换为R,其中R是一个类型变量:R扩展Root
在类AbstractRoot
中声明”
我很困惑AbstractRoot
被声明为实现Root
,因此它应该与为“extendsRoot
”定义的参数兼容。我看不到指定的构造函数调用与类定义之间存在冲突
有人能帮我解决这个难题吗?我卡住了
更新:多亏了下面给出的答案,我才知道哪里出了问题。
SqlRoot
接口的设计确实需要将R
发送到PhraseBuilder
类。为解决此问题,已对代码进行如下修补:
static abstract class AbstractRoot<R extends Root<R>> implements Root<R> {
private final Map<Grouping, Phrase> m_ph;
AbstractSqlRoot() { this.m_ph = new HashMap<>(); }
@Override public PhraseBuilder<R> phrase() {
PhraseBuilder<R> fr = (PhraseBuilder<R>) m_ph.get(Grouping.PHRASE);
if (fr == null) {
--> fr = new PhraseBuilder<R>(typedThis());
m_ph.put(Grouping.PHRASE, fr);
}
return fr;
}
:
:
protected abstract R typedThis();
}
新短语生成器(this)
正在尝试调用此构造函数:
public PhraseBuilder(R r) { super(r); }
问题是,
这个
不是一个R
:它是一个AbstractRoot
,它碰巧也是一个Root
,但它根本不是一个R
。也许你是这个意思
fr = new PhraseBuilder<Root<R>>(this);
fr=新短语生成器(本);
问题在于此
是根
,不一定是R
。听起来很困惑?它是。下面是一个反例,它可能会破裂:
public class MyRootA extends AbstractRoot<MyRootA> {
//R is MyRootA - "this" is an instance of R
}
public class MyRootB extends AbstractRoot<MyRootA> {
//R is MyRootA - "this" is NOT an instance of R
}
在根目录中声明:
R typedThis();
具体类的实现通常只是:
public MyRootA typedThis() {
return this;
}
谢谢你清晰、有用、有用的回答。我现在明白我错在哪里了。当我设计这个API时,我确实需要interfaceSqlRoot
中的方法来返回一个R。如果不重构大量的代码,就无法解决这个问题。因此,新短语生成器(this)
帮不了我。我真的需要一个R
。谢谢你。不幸的是,当我为这些东西设计API时,我真的,真的需要接口SqlRoot
中的方法来返回R
。我明白我错在哪里了。从子类中获取R
的解决方案在API上留下了一个明显的缺点(这个类无论如何都不是导出API的一部分),但它允许我继续前进。谢谢
fr = new PhraseBuilder<R>(this.typedThis());
R typedThis();
public MyRootA typedThis() {
return this;
}