为什么我的自绑定泛型类型与方法调用不匹配?

chr*_*ke- 2 java generics

我正在为如下所示的命令外壳编写代码:

interface Context<C extends Context<C>> {}

interface RecursiveContext<C extends RecursiveContext<C>> extends Context<C> {
  Shell<C> getShell();
  default Result execute(Command cmd) { return getShell().execute(cmd, this); }
}

interface Shell<C extends Context<C>> {
  C newContext();
  Result execute(Command cmd, C context);
}
Run Code Online (Sandbox Code Playgroud)

我在默认方法中遇到错误说

The method execute(Command, C) in the type Shell<C> is not applicable for the arguments (Command, RecursiveContext<C>)
Run Code Online (Sandbox Code Playgroud)

我希望这能奏效,因为Shell<C> getShell()保证能够C在其execute调用中接受并且因为this实际上保证是相同自绑定类型的子类型C,但编译器似乎不同意我的观点。哪里不匹配,在默认方法中执行强制转换是否安全?如果这不安全,你能提供一个类型不匹配的反例吗?

我也试过在 shell 中引入一个中间类型<D extends C> execute(Command, D),但这似乎没有改变任何东西。

(大多数建议的问题都涉及原始类型的中间步骤,但我认为我没有错过。)

Swe*_*per 5

这里问题的核心是CinRecursiveContext并不是真的Self- 实现类的类型。Java 中没有这样的东西,这RecursiveContext<C extends RecursiveContext<C>>只是解决这个问题的一个技巧,而这正是该技巧中断的地方。

假设我有AB。这是有效的:

class A implements RecursiveContext<B> {

    @Override
    public Shell<B> getShell() {
        return new ShellB();
    }
}
class B implements RecursiveContext<B> {

    @Override
    public Shell<B> getShell() {
        return null;
    }
}

class ShellB implements Shell<B>{
    @Override
    public B newContext() {
        return new B();
    }

    @Override
    public Result execute(Command cmd, B context) {
        return new Result();
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以这样做:

new A().execute(new Command());
Run Code Online (Sandbox Code Playgroud)

现在execute将通过this,这是 的一个实例A,进入ShellB.execute

真的有人会这样实施RecursiveContext吗?我想不会!人们理解这种RecursiveContext<C extends RecursiveContext<C>>模式并“接受提示”。编译器没有(因为自定界泛型类型在技术上不是语言功能),并且说C仍然可能与this.