为什么以下使用Cyclic Generics的代码无法编译?

Can*_*ell 9 java generics java-8

以下是我的代码

class A<B2 extends B, A2 extends A<B2, A2>> {
    C<B2, A2> c;

    void test() {
        c.acceptParameterOfTypeA(this);
    }

}

class B {

}

class C<B2 extends B, A2 extends A<B2, A2>> {
    void acceptParameterOfTypeA(A2 a) {

    }
}
Run Code Online (Sandbox Code Playgroud)

错误发生在c.acceptParameterOfTypeA(this);.

错误是

类型C中的方法acceptParameterOfTypeA(A2)不适用于参数(A)

从我看到的,该方法acceptParameterOfTypeA需要一个类型A的参数,并this在给出错误的行是类型A.

我究竟做错了什么?如何解决这个问题?

如果它很重要,我正在使用Java8

Kon*_*kov 8

我将再次重命名您的类,以便一切都更具可读性.那么,我们有:

public class First<T extends Second, U extends First<T, U>> {
    Third<T, U> c;

    void test() {
        c.acceptParameterOfTypeA(this);
    }

}

class Second {

}

public class Third<X extends Second, Y extends First<X, Y>> {
    void acceptParameterOfTypeA(Y a) {

    }
}
Run Code Online (Sandbox Code Playgroud)

cmember(Third<T, U>)的定义,我们可以得出结论,c将使用此签名公开一个方法:

void acceptParameterOfTypeA(U a) { .. }
Run Code Online (Sandbox Code Playgroud)

什么是UU是一个子类型First<T, U>.

但是,如果U可以用替代First类型擦除后,这将意味着First extends First<T, First>,这是不正确的,因为U代表子类型的First,这是参数化一些具体的子类型SecondFirst.

为了达到目的U,您可以应用所谓的Get This方法.

首先,既然你需要U,First但是不能从中获取它First,你可以引入一个abstract返回它的方法:

abstract class First<T extends Second, U extends First<T, U>> {
    Third<T, U> c;

    void test() {
        c.acceptParameterOfTypeA(getU());
    }

    abstract U getU();

}
Run Code Online (Sandbox Code Playgroud)

然后,执行一个样本的子类的First,称为Fourth,它扩展First了一些具体的类型TU,例如:

class Fourth extends First<Second, Fourth> {
    Fourth getU() {
        return this;
    }
}
Run Code Online (Sandbox Code Playgroud)

在该getU()方法中,只需执行return this;此操作将返回U超类中的正确替换.

更多信息: