java - 为什么 Java 编译器不能正确推断继承?

标签 java generics

答案归结为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 被明确定义为同时实现 FooBar;为什么这还不足以满足 Foo & Bar 约束条件?

更新

本练习的主要目标是定义以下契约:在 FooBar 实例上调用方法 foobar 保证返回东西 实现了 FooBar

最佳答案

类型参数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/

相关文章:

java - 什么是原始类型,为什么我们不应该使用它呢?

c# - 使用不带参数的 "params"关键字使用反射调用方法

java - XML 解析器 Jar 混淆

java - Jersey Maven 配置

java - 如何在通常的 java 代码中运行 OSGi 框架?

swift - 泛型的泛型? A<T<U>> 类?

java - 如何在 Java 8 中进行条件方法链接

java - Spring选择了存储库实现,它甚至没有实现存储库接口(interface)

scala - Scala方法上的多个类型参数

java - 这个通用构造函数需要什么才能工作?