Intellij、Maven和Eclipse之间的编译差异



我有一个令人困惑的问题。首先,这里有一个最小代码示例:

public interface I {
<T> T getValue();
}
public abstract class AC<T> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
public class C extends AC<Integer> implements I {
}
public class Main {
public static void main(String[] args) {
final C c = new C();
c.setValue(1);
final Integer i = c.getValue();
System.out.println(i);
}
}

当我尝试使用javac、Intellij或Maven进行编译时,我会得到错误:

C不是抽象的,并且不会覆盖I 中的抽象方法getValue((

如果我在Eclipse中编译程序,它编译成功。

有人能解释一下为什么eclipse能处理这个问题,而其他的都不能?

这里是我的软件版本:

  • Eclipse 2018-09(4.9.0(
  • Intellij 2018.1.3
  • Maven 3.3.1
  • Oracle JDK 8u181

更新:

我向Oracle报告了这个问题,他们可以复制这个问题。这是Oracle编译器(Java bug数据库(中的一个错误

Maven和Intellij都使用(默认情况下(Oracle JDK的javac,而Eclipse有自己的Java编译器。

javac或Eclipse编译器就在这里,由Java语言规范决定。

我相信Eclipse编译器在这里是正确的,因为您的示例将两个分别与两个编译器工作的东西组合在一起,没有任何问题:

  • 通过继承实现接口,例如:
public class ImplementationViaInheritance {
public static void main(String[] args) {
System.out.println(new C1().getClass());
}
}
class SuperC1 {
public void foo() {};
}
interface I1 {
void foo();
}
class C1 extends SuperC1 implements I1 {
// implements I1 via inheritance from SuperC1
}
  • 如果在没有任何抽象方法的情况下扩展抽象类,则不需要方法实现(另请参阅Java语言规范8.1.1.1-abstract Classes(,例如:
public class AbstractClassWithoutAbstractMethods {
public static void main(String[] args) {
System.out.println(new C2().getClass());
}
}
abstract class SuperC2 {
public void foo() {};
}
class C2 extends SuperC2 {
// no methods
}

当您从非抽象类C实现接口I时,需要重写抽象方法getValue((。将您的类C编辑为:

public class C extends AC<Integer> implements I {
public T getValue() {
return value;
}
}

或者您可以在类AC中实现I,就像您在那里实现getValue((方法一样。从类C开始,只需扩展类AC

public abstract class AC<T> implements I {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
public class C extends AC<Integer> {
}

最新更新