为什么Eclipse编译这个,但javac不编译?

时间:2009-07-24 10:14:48

标签: java compiler-construction jls

我们有一些单元测试可以在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编译器可能会错误地允许它不应该存在的东西。

有什么想法吗?

4 个答案:

答案 0 :(得分:7)

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

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

为了让javac与您的with方法匹配

PS

imho是eclipse编译器的错误

答案 1 :(得分:7)

我通过<?,?>Matcher SubMatcher.with添加class SubMatcher extends BaseMatcher { @Override public SubMatcher with(Matcher<?,?> matcher) { return this; } } 来成功构建:

@Override

如果没有这个,方法签名就不同于基础。我想知道{{1}}检查中是否存在未发现此错误的错误。

答案 2 :(得分:0)

检查Eclipse和终端上正在编译的jre或jdk。也许这可能是版本问题。

答案 3 :(得分:0)

适合我:

$ java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-****-2009_07_23_10_21-b00)
OpenJDK 64-Bit Server VM (build 16.0-b06, mixed mode)
$ javac -XDrawDiagnostics Test.java 
$

我依稀记得这样的错误报道,但现在无法给你一个链接。