java - 接口(interface)中的协变返回类型未通过 Javac 编译

标签 java eclipse javac covariant

我有以下结构:

public interface BarReturn {}
public interface FooReturn {}
public interface FooBarReturn extends FooReturn, BarReturn {}

public interface Foo {  
  FooReturn fooBar( );
}

public interface Bar {
  BarReturn fooBar();
}

public interface FooBar extends Foo, Bar {
  FooBarReturn fooBar();
}

Javac 失败并显示以下消息:

FooBar.java:2: types Bar and Foo are incompatible; both define fooBar(), but with unrelated return types
public interface FooBar extends Foo, Bar {
       ^
1 error

但是,Eclipse 可以很好地编译它,据我所知它应该可以编译 - FooBar 的 fooBar() 方法通过使用协变返回满足 Foo 和 Bar 的 fooBar() 方法的约定。

这是 Eclipse 编译或 javac 中的错误吗?或者有没有办法说服 javac 编译它?作为引用,我的 javac 选项如下所示:

javac -d /tmp/covariant/target/classes -sourcepath /tmp/covariant/src/main/java: /tmp/covariant/src/main/java/Foo.java /tmp/covariant/src/main/java/BarReturn.java /tmp/covariant/src/main/java/FooBarReturn.java /tmp/covariant/src/main/java/Bar.java /tmp/covariant/src/main/java/FooReturn.java /tmp/covariant/src/main/java/FooBar.java -g -nowarn -target 1.6 -source 1.6

最佳答案

您在 FooBar 接口(interface)中扩展了 Foo 和 Bar。因此,您继承了两种返回类型不兼容的方法。 Java 协方差仅在遵循 Liskov 替换时才允许。也就是说,覆盖的候选类型必须几乎是覆盖的返回类型的子类。

在你上面的例子中,像这样的东西应该编译:

public interface BarReturn {}
public interface FooReturn {}
public interface FooBarReturn extends FooReturn, BarReturn {}

public interface Foo {  
  FooReturn fooBar( );
}

public interface FooBar extends Foo{
  FooBarReturn fooBar();
}

关于java - 接口(interface)中的协变返回类型未通过 Javac 编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7056485/

相关文章:

Java-Selenium : Eclipse is unable to find my file, 但我的文件位于其工作目录中

java - 相同 JDK 上的相同代码可以在 Eclipse 上编译,但会在 Netbeans、IDEA 或命令行上导致类型不可转换

java - 如何调试 Rails 应用程序?

java - 无法通过 MavenCli (maven-embedder) 运行 maven 任务

java - EasyMock - 匹配器与原始值混合?

java - 带弧标志的最短路径问题 dijkstra

java - lubuntu错误编译代码

eclipse - 将eclipse项目.classpath依赖项提取到ant脚本中

java - 如何在 Java 中使用具有 session 失效的 Tomcat CSRF 保护过滤器

java - 如何在 Android 中检测整个图像已下载