【问题标题】:Eclipse fails where javac and IDEA succeedEclipse 在 javac 和 IDEA 成功的地方失败
【发布时间】:2015-06-03 18:23:13
【问题描述】:

考虑以下独立示例:

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 无法编译标有&lt;-- ERROR 的行,并给出以下消息:

The constructor Blooper5.ConvertingIdentifier&lt;Annotation,Class&lt;capture#5-of ? extends Annotation&gt;&gt;(Blooper5.Converter&lt;Class&lt;? extends Annotation&gt;,Annotation&gt;) 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_40,在Project Structure/Modules 下,特定模块配置为使用列为1.8 (java version "1.8.0_40") 的“Project SDK (1.8)”。

至于 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 下,它也被检查为“JavaSE-1.8”的“兼容 JRE”。在我的Project/Properties/Java Build Path/Libraries 中,“JRE 系统库”是[jdk1.8.0_40]

更多值得注意的事实:

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

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

那么,问题来了:

是什么导致了 Eclipse 与其他系统之间的这些差异,以及可以采取哪些措施来消除这些差异?

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

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

【问题讨论】:

  • 您使用的是哪个 Eclipse?在 Luna(4.4.0 版)上运行良好
  • @RohitJain wh00ps,抱歉遗漏,我更新了问题以包含该信息。所以,我也在使用 Luna 4.4.0。 O_O
  • 我也可以在 Eclipse Luna 上重现这个。
  • 这很奇怪。 Rohit Jain 无法复制它,E-Riz 可以。

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


【解决方案1】:

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

最好的办法是像我一样将其报告为 Eclipse 错误,然后查看 Eclipse 编译器团队是否能够/将追踪它。

【讨论】:

    猜你喜欢
    • 2010-12-09
    • 2020-10-13
    • 2017-08-16
    • 2011-09-27
    • 2012-11-04
    • 2015-09-26
    • 1970-01-01
    • 2020-12-29
    相关资源
    最近更新 更多