Generics Oracle JDK和Eclipse JDT编译器不同意!哪个编译错误了?异常泛型与推理

Generics Oracle JDK和Eclipse JDT编译器不同意!哪个编译错误了?异常泛型与推理,generics,java,eclipse-jdt,compiler-bug,Generics,Java,Eclipse Jdt,Compiler Bug,我有一段代码在OracleJDK7和EclipseJDT7之间编译时不一致,但由于我不确定是哪个编译器出错,我想在提交任何错误报告之前,我应该在这里征求意见 这是我能想到的证明不一致性的最简单测试: interface Foo<S extends Foo<S, T>, T> { // should this compile? public <X extends Foo<S, Y>, Y> Y method1(); // w

我有一段代码在OracleJDK7和EclipseJDT7之间编译时不一致,但由于我不确定是哪个编译器出错,我想在提交任何错误报告之前,我应该在这里征求意见

这是我能想到的证明不一致性的最简单测试:

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> Y method2();
}
接口Foo{
//这个应该编译吗?
公共卫生方法1();
//这个怎么样?

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

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

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

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


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

我只能想象这个应用code@hoaz-原始代码确实非常愚蠢且过于复杂;)。这里的所有内容都发生了很大的变化,但是当我们引用Foo时,如果只正确地设置了S参数,那么以其原始形式的方法的想法是一种获得T类型的“魔术”。在我们的示例中t看起来像:
Foo-fooBar=null;Integer-something=fooBar.method1()
@EliasVasylenko-但是你在NetBeans或者JDK 5/6/7中试过吗?我写了一些复杂的泛型代码,我在JDK和Eclipse中编译过,但是在NetBeans编辑器中发现它失败了。经验教训-不要尝试嵌套太多的参数化类型。哇。如果这只是为了好玩和锻炼你的泛型肌肉而写的,那么给你更多的权力!但是,如果你希望这段代码投入生产并由你以外的人(甚至是5年后的你)维护多年,那么我会远离这一点。让你的代码更简单、更易于维护,每个人都会很高兴。也就是说,在这两个编译器上都有一个bug是值得的(JDK和Oracle)。Y的目的是,对于X的某些参数化,它是不可参数化的,通过代理在X上给出了一种边界……你对Y被忽略的解释听起来很有道理(尽管对我来说仍然听起来像是个错误),但当您将鼠标悬停在eclipse中的调用上时,它会告诉您推断的参数化是
Foo
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>, 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();
    }
}