超类方法和接口默认方法冲突解决

时间:2015-09-09 04:59:38

标签: java eclipse java-8 default-method

考虑下面的例子,

public class Testing extends SupCls implements Intf {
    public static void main(String[] args) {
        new Testing().test();
    }
}

class SupCls {
    public void test() {
        System.out.println("From SupCls");
    }
}

interface Intf {
    public default void test() {
        System.out.println("From Intf");
    }
}

如您所见,SupCls类和Intf接口之间没有任何关联。但两者都定义一种常用方法。

Testing课程正在推广SupCls并实施Intf

因此,当我在test()上调用Testing方法时,输出为

From SupCls

我认为这是有道理的,因为从类扩展应该比从接口实现更高的优先级。

但是eclipse报告不然,如下面的屏幕截图所示。

Screen Capture of Eclipse

我坚信这是Eclipse中的错误

但在假设之前,是否已定义此行为&记录在 JLS 中?或者还有其他什么来定义这种行为?

编辑:Eclipse版本 Mars Release(4.5.0),如果重要的话。

3 个答案:

答案 0 :(得分:9)

您的假设是正确的,从超类继承的具体方法优先于default中的interface方法:

JLS §8.4.8. Inheritance, Overriding, and Hiding

  

C 从其直接超类继承并直接重叠所有abstract和默认(§9.4)方法m,以下所有方法都是真:

     

...

     
      
  • C中声明的方法没有签名是m签名的子签名(第8.4.2节)。
  •   
  • C从其直接超类继承的具体方法没有签名,该签名是m签名的子签名。
  •   

第二个引用的子弹适用于此处,有一个从具有适当签名的直接超类继承的具体方法,因此default方法不会被继承。

文档甚至可以通过额外的评论清除任何疑问:

  

请注意,继承的具体方法可能会阻止抽象或默认方法的继承。 (稍后我们将声明具体方法覆盖了“来自C”的抽象或默认方法。)

因此SupCls.test()就类Intf.test()而言覆盖Testing

换句话说,你是对的,这是Eclipse中的一个错误,但只要它只影响提案的呈现方式,我就认为它是次要的错误。无论是否在提案中呈现 D ,插入的源都是相同的。

答案 1 :(得分:5)

这肯定是eclipse中的一个错误,但在代码完成提案中而不是在编译器中。将鼠标悬停在测试或打开声明的调用上,将转到SupCls方法并正确运行代码,打印“From SupCls”,证明了这一点。请提交针对jdt ui进行调查的错误

答案 2 :(得分:2)

看起来eclipse版本很重要!

在Eclipse Luna(4.4.1)中,引用指向SupCls而不是Intf

enter image description here

可能是Eclipse Mars中的一个错误