首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Eclipse/javac不同意使用默认方法冲突编译签名;谁是对的?

Eclipse/javac不同意使用默认方法冲突编译签名;谁是对的?
EN

Stack Overflow用户
提问于 2017-08-21 21:21:21
回答 2查看 986关注 0票数 17

下面是一个简单的类来演示这个问题:

代码语言:javascript
复制
package com.mimvista.debug;

public class DefaultCollisionTest {
    public static interface Interface1 {
        public String getName();
    }

    public static interface Interface2 {
        public default String getName() { return "Mr. 2"; };
    }

    public static <X extends Interface1&Interface2> String extractName(X target) {
        return target.getName();
    }
}

Eclipse (Neon2)愉快地编译这个类,而javac (JDK 1.8.0_121)则显示以下编译错误:

代码语言:javascript
复制
$ javac src/com/mimvista/debug/DefaultCollisionTest.java
src\com\mimvista\debug\DefaultCollisionTest.java:13: error: class INT#1 inherits abstract and default for getName() from types Interface2 and Interface1
        public static <X extends Interface1&Interface2> String extractName(X target) {
                       ^
  where INT#1 is an intersection type:
    INT#1 extends Object,Interface1,Interface2
1 error

我相信Eclipse在这种情况下是正确的,但我不能完全确定。根据我对“继承抽象和默认”错误的理解,我认为只有在编译实现这两个接口的实际声明类时才应该生成它。看起来javac可能在幕后生成一个中间类来处理泛型签名,并错误地将其置于默认方法冲突测试之下?

EN

回答 2

Stack Overflow用户

发布于 2017-08-21 22:08:45

据我所知,这个问题是关于将已编译类的对象作为参数传递的。由于不能使用抽象类或接口调用extractName(X)方法,因此argument对象必须解析其getName()方法并且明确无误。javac使用后期绑定来解析在运行时调用哪个被覆盖的方法,因此我同意BonusLord的观点,即即使Java抛出错误,该方法也可以正确编译和运行。

票数 1
EN

Stack Overflow用户

发布于 2017-08-22 02:03:39

我会说这是一个Javac bug,或者至少它应该是。

看起来Javac的实现者走了一条捷径,在泛型边界的实现中重用了创建接口的代码。实际上,Javac对待<X extends I1&I2>就像对待interface X extends I1, I2一样。

然而,在现实中,<X extends I1&I2>是不同的。这只意味着X同时拥有I1I2的方法,但没有说明这些方法的实现。因此,是否存在default实现应该是无关紧要的。

不幸的是,正如@slim所说,目标是通过JDK的编译器,所以Javac拥有最终决定权。也许可以提交一份bug报告?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45798233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档