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

2022-09-03 14:55:38

众所周知,可以在Java中实现多个。其执行顺序是否重要?我的意思是,实现B,C是否与C,B相同?我的测试显示顺序确实很重要 - 但任何人都可以解释这背后的逻辑吗?interfacesJava 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 {

}

上面的代码工作正常。如果我将顺序更改为 ,它将给出一个错误:B, CC, BThe default method display() inherited from B conflicts with another method inherited from C.

public interface D extends C, B {

}

编辑

我正在使用Eclipse(Mars)。杰德克 .杰瑞 .jdk1.8.0_51jre1.8.0_60


答案 1

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

从 A.B 继承的默认方法 display() 与从 A.C 继承的另一种方法冲突

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

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

或翻拍抽象display()

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

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


答案 2

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

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

来自 ecj 4.4 的 resuls:

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

来自 ecj >= 4.4.1 的 resuls:

NO ERROR

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

我的结论是,这是Eclipse中的一个错误,它在4.4.1中引入。我已经提交了错误477891以进行跟进。

编辑:bug 477891已在面向 Eclipse 4.6 的 Milestone 3 中修复(GA:2016 年 6 月)。