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

Pra*_*uja 15 java interface java-8 default-method

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

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 {

}
Run Code Online (Sandbox Code Playgroud)

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

public interface D extends C, B {

}
Run Code Online (Sandbox Code Playgroud)

编辑

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

dka*_*zel 8

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

从AB继承的默认方法display()与从AC继承的另一个方法冲突

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

public interface D extends B, C {
    default void display(){
        B.super.display();
    }
}
Run Code Online (Sandbox Code Playgroud)

或重拍display()抽象

interface D extends B, C {
    public void display();
}
Run Code Online (Sandbox Code Playgroud)

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

  • D也可以将`display()`重新断言为abstract. (2认同)

Ste*_*ann 6

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

error: interface D inherits abstract and default for display() from types B and C
Run Code Online (Sandbox Code Playgroud)

来自ecj 4.4的结果:

The default method display() inherited from B conflicts with another method inherited from C
Run Code Online (Sandbox Code Playgroud)

来自ecj > = 4.4.1:

NO ERROR
Run Code Online (Sandbox Code Playgroud)

如果D更改了's extends子句中的顺序,则仍然ecj> = 4.4.1正确报告错误.

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

编辑: 错误477891已在里程碑3中修复到Eclipse 4.6(GA:2016年6月).