答案归结为Java 不支持参数化方法的下界,因为这样的功能“不够有用”
,请引用similar question
给定以下代码段:
package demo;
public class Demo {
interface Foo { void foo(); }
interface Bar { void bar(); }
interface FooBar {
<R extends Foo & Bar> R foobar();
static FooBar create() { return new TypicalJavaFooBar(); }
}
private static final class TypicalJavaFooBar implements Foo, Bar, FooBar {
public void bar() { System.out.println("foo"); }
public void foo() { System.out.println("bar"); }
public <R extends Foo & Bar> R foobar() {
return (R) this;
}
}
public static void main(String[] args) {
FooBar x = FooBar.create();
Foo foo = x.foobar();
Bar bar = x.foobar();
x.foobar().foo();
x.foobar().bar();
}
}
在 TypicalJavaFooBar#foobar
中没有显式转换为 R
编译器失败并出现以下错误
Error:(13, 20) java: incompatible types: demo.Demo.TypicalJavaFooBar cannot be converted to R
我的问题是为什么?对我来说,似乎编译器应该有足够的信息,因为 TypicalJavaFooBar
被明确定义为同时实现 Foo
和 Bar
;为什么这还不足以满足 Foo & Bar
约束条件?
更新
本练习的主要目标是定义以下契约:在 FooBar
实例上调用方法 foobar
保证返回东西 实现了 Foo
和 Bar
。
最佳答案
类型参数R
通过调用代码绑定(bind)到方法,理论上可以是Baz implements Foo, Bar
;参见,例如,Collections.emptySet()
,其类型参数由调用者确定,并且会受到类型见证的影响。
要执行您显然正在尝试的操作,您需要将类型参数移动到接口(interface)上 FooBar
并且有TypicalJavaFooBar implements Foo, Bar, FooBar<TypicalJavaFooBar>
.
关于java - 为什么 Java 编译器不能正确推断继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35021967/