为什么在Java 8中实现接口(使用默认方法)的顺序很重要?

时间:2015-09-19 02:38:09

标签: java interface java-8 default-method

众所周知,多个interfaces可以用Java实现。他们的实施顺序是否重要?我的意思是,实施B,C与Java 8中的C,B相同?我的测试表明订单确实很重要 - 但任何人都可以解释这背后的逻辑吗?

public interface A {
    public default void display() {
        System.out.println("Display from A");
    }
}

public interface B extends A {
    public default void display() {
        System.out.println("Display from B");
    }
}

public interface C extends A {
    public void display();
}

public interface D extends B, C {

}

上面的代码工作正常。如果我将订单B, C更改为C, B,则会出错:The default method display() inherited from B conflicts with another method inherited from C.

public interface D extends C, B {

}

修改

我正在使用Eclipse(火星)。 JDK jdk1.8.0_51。 JRE jre1.8.0_60

2 个答案:

答案 0 :(得分:8)

无论哪种方式都应该出现错误消息。当我使用jdk 1.8.0_31时,无论接口的顺序如何,我都会收到以下错误:

  

从A.B继承的默认方法display()与从A.C

继承的另一个方法冲突

解决方案是覆盖display()中的D,甚至只是告诉编译器使用哪个超类的实现:

public interface D extends B, C {
    default void display(){
        B.super.display();
    }
}

或重拍display()摘要

interface D extends B, C {
    public void display();
}

如果您确实使用比我更高的版本收到此错误,那么可能值得提交错误报告吗?

答案 1 :(得分:6)

javac (所有版本1.8.0_x)的结果:

error: interface D inherits abstract and default for display() from types B and C

来自 ecj 4.4:

The default method display() inherited from B conflicts with another method inherited from C

来自 ecj > = 4.4.1:

NO ERROR

如果D的扩展条款中的顺序发生更改,则仍然ecj> = 4.4.1正确报告错误。

我得出结论,这是Eclipse中的一个错误,它在4.4.1中引入。我已提交bug 477891跟进。

编辑 bug 477891已在里程碑3中修复为Eclipse 4.6(GA:2016年6月)。