加入收藏 | 设为首页 | 会员中心 | 我要投稿 新余站长网 (https://www.0790zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

Oracle JDK和Eclipse JDT编译器不一致!哪个不正确地编译?不寻

发布时间:2021-01-12 20:13:55 所属栏目:站长百科 来源:网络整理
导读:我有一段代码在Oracle JDK 7和 Eclipse JDT 7之间编译不一致,但由于我不确定哪个编译器犯了错误,我认为在提交任何错误报告之前我应该??在这里征求意见. 这是我可以提出的最简单的测试来证明不一致性: interface FooS extends FooS,T,T { // should this com

我有一段代码在Oracle JDK 7和 Eclipse JDT 7之间编译不一致,但由于我不确定哪个编译器犯了错误,我认为在提交任何错误报告之前我应该??在这里征求意见.

这是我可以提出的最简单的测试来证明不一致性:

interface Foo<S extends Foo<S,T>,T> {
    // should this compile?
    public <X extends Foo<S,Y>,Y> Y method1();

    // what about this?
    public <X extends Foo<? extends S,Y> Y method2();
}

Oracle JDK在method1上给出了错误,但没有给出method2,而Eclipse对这两种方法都没有问题.我甚至不确定任何一种方法都应该编译……

如果这两个方法都不应该编译开始,那么以下几点没有实际意义,但我觉得如果我们添加以下代码,两个编译器都会出错:

interface Bar extends Foo<Bar,Integer> {
}

class Bug {
    void bug() {
        Bar bar = null;
        Double bubble;

        // these fail as expected...
        bar.<Foo<Bar,Double>,Double> method1();
        bar.<Foo<? extends Bar,Double> method2();

        // ...but these don't even though the inferred parametrisations should be
        // the same as above
        Double bobble = bar.method1();
        Double babble = bar.method2();
    }
}

当我们为method1和method2提供显式参数化时,我找不到任何会导致返回Double的有效调用(即,当使用Double参数化时,我找不到X的有效参数化).这是我期望的行为,就我所见,这里的Y应该只能用Integer参数化.

但是,当我们让编译器推断参数化时,Oracle JDK和Eclipse JDT都允许使用Y推断的调用为Double.如果将鼠标悬停在Eclipse中的调用上,它甚至会显示参数化与我们手动失败的参数化完全相同,那么为什么不同的行为呢?

(此时分配给新变量bobble和babble的原因是悬停文本显示不同的参数 – 由于某种原因将Double替换为Object – 如果我们再次分配给bubble.它仍然编译两个调用并分配给双打,所以我不知道为什么会这样.)

所以,这可能是我的另一个相当含糊的问题,但是这里的任何人都可以为我阐明这一点吗?

编辑:

Eclipse的错误报告:https://bugs.eclipse.org/bugs/show_bug.cgi?id=398011

解决方法

似乎编译器做了某种简化. Foo.method1和Foo.method2用两个参数X和Y声明,其中一个参数可以在推断期间确定,但是根本不使用X.

因此,当您调用Double bobble = bar.method1()时,X应该计算为extends Foo< Bar,但编译器决定删除此参数,因为它未被使用.

当您明确指定方法参数时,编译器必须检查它们的正确性并按预期失败.

如果您更改这些方法中的任何一个以接受类型X的参数,那么您将不会得到这种模糊的情况,因为您将为编译器提供一些信息,用于确定实际的X.

当Eclipse编译器根本没有显示任何错误时,Eclipse有几个这样的错误,但是javac开始抱怨不正确的方法调用.避免此类错误的最佳方法是使用显式参数,在这种情况下,大多数编译器的行为几乎相同.因此,如果您对显式参数有问题,最好重新设计您的类.

(编辑:新余站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读