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
,因此它应该与为“extends
Root
”定义的参数兼容。我看不到指定的构造函数调用与类定义之间存在冲突

有人能帮我解决这个难题吗?我卡住了


更新:多亏了下面给出的答案,我才知道哪里出了问题。
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时,我确实需要interface
SqlRoot
中的方法来返回一个R。如果不重构大量的代码,就无法解决这个问题。因此,
新短语生成器(this)
帮不了我。我真的需要一个
R
。谢谢你。不幸的是,当我为这些东西设计API时,我真的,真的需要接口
SqlRoot
中的方法来返回
R
。我明白我错在哪里了。从子类中获取
R
的解决方案在API上留下了一个明显的缺点(这个类无论如何都不是导出API的一部分),但它允许我继续前进。谢谢
 fr = new PhraseBuilder<R>(this.typedThis());
 R typedThis();
 public MyRootA typedThis() {
    return this;
 }