接口中的协变返回类型未通过 Javac 编译 [英] Covariant Return Type in Interface not compiling via Javac
问题描述
我有以下结构:
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 失败并显示以下消息:
Javac fails with the following message:
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() 方法的约定.
However, Eclipse can compile it fine, and as far as I can see it should compile - FooBar's fooBar() method satisfies the contract of both Foo and Bar's fooBar() method by using covariant returns.
这是 Eclipse 编译或 javac 中的错误吗?或者有没有办法说服javac编译它?作为参考,我的 javac 选项如下所示:
Is this a bug in the Eclipse compile or in javac? Or is there a way to persuade javac to compile it? For reference my javac options look like this:
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 界面中扩展 Foo 和 Bar.因此,您继承了两个返回类型不兼容的方法.仅当遵循 Liskov 替换时才允许 Java 协变.也就是,覆盖候选类型几乎必须是覆盖返回类型的子类.
You are extending both Foo and Bar in your FooBar interface. As such you are inheriting two methods with incompatible return types. Java co-variance is only allowed when it follows Liskov substitution. Aka, the overriding candidate types must pretty much be a subclass of the overridden return type.
在上面的示例中,应该编译:
In your example above something like this should compile:
public interface BarReturn {}
public interface FooReturn {}
public interface FooBarReturn extends FooReturn, BarReturn {}
public interface Foo {
FooReturn fooBar( );
}
public interface FooBar extends Foo{
FooBarReturn fooBar();
}
这篇关于接口中的协变返回类型未通过 Javac 编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!