【问题标题】:Why does Eclipse compile this, but javac doesn't?为什么 Eclipse 编译这个,而 javac 没有?
【发布时间】:2009-07-24 10:14:47
【问题描述】:

我们有一些在 Eclipse 3.4 中编译和运行良好的单元测试,但是当我们尝试使用 javac 编译它们时,它失败了。我已经设法将代码缩减为小而独立的代码,因此它没有外部依赖项。代码本身没有多大意义,因为它完全脱离了上下文,但这没关系 - 我只需要找出 javac 不喜欢这样的原因:

public class Test {

    public void test() {
        matchOn(someMatcher().with(anotherMatcher()));
    }

    void matchOn(SubMatcher matcher) {}

    SubMatcher someMatcher() {
        return new SubMatcher();
    }

    Matcher anotherMatcher() {
        return null;
    }
}

interface Matcher <U, T> {}

class BaseMatcher implements Matcher {
    public BaseMatcher with(Matcher<?,?> matcher) {
        return this;
    }
}

class SubMatcher extends BaseMatcher {
    @Override
    public SubMatcher with(Matcher matcher) {
        return this;
    }
}

我试过JDK 1.5.0_101.6.0_13,结果一样:

Test.java:6: matchOn(test.SubMatcher) in test.Test cannot be applied to (test.BaseMatcher)
                matchOn(someMatcher().with(anotherMatcher()));
                ^
1 error

我认为这是完全有效的 Java。 SubMatcher.with() 方法返回比 BaseMatcher.with() 更具体的类型,但编译器似乎认为返回类型是 BaseMatcher。但是,Eclipse 编译器可能错误地允许了不应该允许的内容。

有什么想法吗?

【问题讨论】:

  • 我可以在 Linux 上使用 jdk 1.6 重现此编译器错误。似乎 Java 1.5 引入的协变返回类型在此示例中无法正常工作。

标签: java compiler-construction jls


【解决方案1】:

在 BaseMatcher 中需要指定类型参数:

public SubMatcher with(Matcher<?, ?> matcher) {

为了让javac匹配你的with方法

PS

imho 是 eclipse 编译器的一个 bug

【讨论】:

  • 你自己和格雷格都得到了答案,但我必须把奖品给别人,你稍微快一点……
【解决方案2】:

我通过在SubMatcher.with 中将&lt;?,?&gt; 添加到Matcher 使其构建成功:

class SubMatcher extends BaseMatcher {
    @Override
    public SubMatcher with(Matcher<?,?> matcher) {
        return this;
    }
}

没有这个,方法签名与基础不同。我想知道@Override 检查中是否存在没有注意到这一点的错误。

【讨论】:

  • 这是一个有趣的情况。您可能会争辩说 javac 在这里有问题,因为它允许使用 @Override 注释,但是它使用子类方法而不是被覆盖的方法。这是不一致的,注释是为了防止这种问题。问题是带有原始类型参数的方法是否可以用 > 覆盖具有相同类型的超类方法
【解决方案3】:

在 Eclipse 和终端上检查您正在使用哪个 jre 或 jdk 进行编译。可能是版本问题。

【讨论】:

  • Eclipse 使用的是 1.5.0_10 JRE,与我正在尝试的 javac 相同。
  • Eclipse 有自己的编译器,即它不使用 javac
【解决方案4】:

为我工作:

$ java -版本 openjdk 版本“1.7.0-内部” OpenJDK 运行时环境(构建 1.7.0-internal-****-2009_07_23_10_21-b00) OpenJDK 64 位服务器 VM(内部版本 16.0-b06,混合模式) $ javac -XDrawDiagnostics Test.java $

我依稀记得这样一个错误报告,但现在不能给你一个链接。

【讨论】:

    猜你喜欢
    • 2012-02-14
    • 1970-01-01
    • 2011-03-04
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2012-04-20
    相关资源
    最近更新 更多