Eclipse 在 javac 和 IDEA 成功的地方失败

Eclipse fails where javac and IDEA succeed

考虑以下独立示例:

package bloopers;

import java.lang.annotation.Annotation;

public final class Blooper5
{
    interface Converter<T,F>
    {
        T convert( F from );
    }

    interface Identifier<T>
    {
    }

    static class ConvertingIdentifier<F,T> implements Identifier<F>
    {
        ConvertingIdentifier( Converter<T,F> converter )
        {
        }
    }

    static final class AnnotationIdentifier
    {
        Identifier<Annotation> I1 = new ConvertingIdentifier<>( 
            a -> a.annotationType() );
        Identifier<Annotation> I2 = new ConvertingIdentifier<>( 
            Annotation::annotationType ); //<-- ERROR
        Identifier<Annotation> I3 = new ConvertingIdentifier<>( 
            (Converter<Class<? extends Annotation>,Annotation>)
            Annotation::annotationType );
    }
}

上面的代码在以下情况下编译得很好:

但是编译失败:

Eclipse 无法编译标有 <-- ERROR 的行,给出以下消息:

The constructor Blooper5.ConvertingIdentifier<Annotation,Class<capture#5-of ? extends Annotation>>(Blooper5.Converter<Class<? extends Annotation>,Annotation>) is undefined

不可否认,这段代码确实推动了编译器的泛型参数类型推断功能,但我仍然想知道差异到底是什么,无论差异有多大。

公开我的一些方法,以防有人发现我看不到的错误:

我用javac编译的命令是"c:\Program Files\Java\jdk1.8.0_40\bin\javac" Blooper5.java.

我有 14.1 版的 IntelliJ IDEA。在 Project Structure/SDKs 下,我只有指向 C:\Program Files\Java\jdk1.8.0_40 的“1.8”,在 Project Structure/Modules 下,特定模块配置为使用 "Project SDK (1.8)",它列为 1.8 (java version "1.8.0_40")

至于Eclipse,我用的是Eclipse for RCP and RAP Developers - Version: Luna Release (4.4.0) - Build id: 20140612-0600Preferences/Java/Installed JREs下我只有jdk1.8.0_40,而且是默认的。在 Execution Environments 下,它也被检查为 "Compatible JRE" of "JavaSE-1.8"。在我的 Project/Properties/Java Build Path/Libraries 中 "JRE System Library" 是 [jdk1.8.0_40].

更多值得注意的事实:

所以,问题:

是什么导致了 Eclipse 与其他 Eclipse 之间的这些差异,如何消除这些差异?

(显然,目标是消除不幸的过于频繁发生的情况,即一个开发人员提交的代码无法在另一个开发人员的 IDE 上编译。)

编辑:当我最初发布这个问题时,我认为 IDEA 使用 Eclipse 编译器也编译得很好,但我错了。原来是可以通过选择Eclipse编译器让IDEA编译上面的代码失败。不过,问题是为什么 eclipse 和 javac 之间存在差异。

"why is there a discrepancy" 的答案很简单,但可能不是很令人满意:因为编译器有错误,而且对非常复杂的语言规范的解释持开放态度。确定它是 javac 还是 Eclipse 中的错误是一项艰巨的任务;我已经看到这种差异最终以两种方式声明,有时作为 Eclipse 编译器错误,有时作为 javac 错误。这种决定,尤其是当它涉及泛型和新的语言特性(如 lambda)时,可能会变得非常乏味和神秘。例如,看看这个结果是 javac 错误但确实在 Eclipse 的编译器中发现了一个相关问题:https://bugs.eclipse.org/bugs/show_bug.cgi?id=456459

最好的办法是像我一样将它报告为 Eclipse 错误,看看 Eclipse 编译器团队 can/will 是否能找到它。