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

时间:2015-03-30 16:19:41

标签: java eclipse intellij-idea java-8 javac

考虑以下自包含样本:

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 );
    }
}

上面的代码在以下内容下编译得很好:

  • javac来自命令行。
  • IntelliJ IDEA配置为使用javac编译器。

但它无法编译以下内容:

  • Eclipse
  • IntelliJ IDEA配置为使用Eclipse编译器。

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

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

至于Eclipse,我正在使用Eclipse for RCP and RAP Developers - Version: Luna Release (4.4.0) - Build id: 20140612-0600。在Preferences/Java/Installed JREs下我只有jdk1.8.0_40,这是默认值。在Execution Environments下,它也会被检查为&#34;兼容的JRE&#34; &#34; JavaSE-1.8&#34;。在我的Project/Properties/Java Build Path/Libraries&#34; JRE系统库&#34;是[jdk1.8.0_40]

更值得注意的事实:

  • 这不仅仅是我;它也失败了同事的(非常相似的)eclipse安装。

  • IntelliJ IDEA表示lambda表达式a -> a.annotationType()可以替换为方法引用,但如果要求这样做,则 将其转换为Annotation::annotationType;相反,它会将其转换为(Converter<Class<? extends Annotation>, Annotation>) Annotation:: annotationType

所以,问题是:

导致Eclipse与其他人之间存在这些差异的原因是什么,以及如何消除这些差异?

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

编辑:当我最初发布这个问题时,我认为使用Eclipse编译器的IDEA也编译得很好,但我错了。事实证明,通过选择Eclipse编译器,IDEA可能无法编译上述代码。不过,问题是为什么eclipse和javac之间存在差异。

1 个答案:

答案 0 :(得分:4)

&#34>答案为什么会出现差异&#34;很简单,但也许不是很令人满意:因为编译器有错误,而且对于非常复杂的语言规范的解释更加开放。确定它是否是javac或Eclipse中的错误是一项艰巨的任务;我已经看到这种差异最终被双重声明,有时候是Eclipse编译器错误,有时候是javac错误。这种决心,特别是涉及泛型和新语言特征(如lambdas)时,可能会变得相当乏味和神秘。例如,看看这个被证明是javac bug的那个,但确实发现了Eclipse编译器中的一个相关问题:https://bugs.eclipse.org/bugs/show_bug.cgi?id=456459

最好的办法是像我一样将它报告为Eclipse错误,看看Eclipse编译器团队是否可以/将跟踪它。