问题描述
我有以下结构:
public interface BarReturn {}
public interface FooReturn {}
public interface FooBarReturn扩展FooReturn,BarReturn {}
public interface Foo {
FooReturn fooBar();
}
public interface Bar {
BarReturn fooBar();
}
public interface FooBar扩展Foo,Bar {
FooBarReturn fooBar();
}
Javac失败,并显示以下消息:
FooBar.java:2:类型Bar和Foo不兼容;都定义fooBar(),但是使用不相关的返回类型
$ p $然而,Eclipse可以编译好,据我所知,应该编译 - FooBar的fooBar()方法满足Foo和Bar的fooBar()方法的合同,使用协变回报。
public interface FooBar extends Foo,Bar {
^
1 error
这是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中扩展Foo和Bar接口。因此,您继承了具有不兼容返回类型的两种方法。只有当跟随Liskov替换时,才允许Java协方差。 Aka,首选的候选类型必须几乎是覆盖的返回类型的子类。
在上面的例子中,这样的应该编译:
公共接口BarReturn {}
public interface FooReturn {}
public interface FooBarReturn扩展FooReturn,BarReturn {}
public interface Foo {
FooReturn fooBar();
}
public interface FooBar extends Foo {
FooBarReturn fooBar();
}
I have the following structure:
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 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
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.
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
解决方案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进行编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!