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

Mik*_*kis 6 java eclipse javac intellij-idea java-8

请考虑以下自包含示例:

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 );
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 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我只有"1.8"指向C:\Program Files\Java\jdk1.8.0_40Project Structure/Modules特定模块下配置使用"项目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-0600.在Preferences/Java/Installed JREs我只有jdk1.8.0_40,它是默认值.在Execution Environments它下面也被检查为"JavaSE-1.8"的"兼容JRE".在我Project/Properties/Java Build Path/Libraries的"JRE系统库"中[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之间存在差异.

E-R*_*Riz 4

“为什么存在差异”的答案很简单,但可能不太令人满意:因为编译器存在错误,而且还可以解释非常复杂的语言规范。确定这是 javac 还是 Eclipse 中的错误是一项艰巨的任务;我见过这样的差异最终以两种方式声明,有时作为 Eclipse 编译器错误,有时作为 javac 错误。这种决定,尤其是当它涉及泛型和新的语言特性(例如 lambda)时,可能会变得相当乏味和神秘。例如,看看这个原来是 javac bug,但确实在 Eclipse 编译器中发现了相关问题:https: //bugs.eclipse.org/bugs/show_bug.cgi?id=456459

最好的选择是像我一样将其报告为 Eclipse bug,然后看看 Eclipse 编译器团队是否可以/将跟踪它。