7

hamcrest 库中有一个方法:

package org.hamcrest.core

...

public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second) {
    List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(2);
    matchers.add(first);
    matchers.add(second);
    return allOf(matchers);
}

在我的代码中,我用firstbeingMatcher<Object>secondbeing 来调用这个方法Matcher<SomeException>

现在:

  • 当我使用带有 1.6 目标的 Eclipse 编译它时,它会生成<T> Matcher<SomeException>.
  • 当我使用带有 1.6 目标的 javac 1.7 编译它时,它会生成<T> Matcher<SomeException>.
  • 当我使用带有 1.6 目标的 javac 1.6 编译它时,它使<T> Matcher<Object>

问题是,<T>在这种情况下应该怎么做?

我的理解是,javac 1.6 中存在一个错误,它应该是Matcher<SomeException>,因为这是输入参数的常见类型(SomeException 是 Object 的子类型),然后,100% 肯定返回的 Matcher 将是Matcher<SomeException>.

我对吗?有没有办法强制 javac 1.6 正常运行?

4

2 回答 2

3

编译器将根据实际参数进行推断。它将从 和 的初始约束Matcher<Object> << Matcher<? super T>开始Matcher<SomeException> << Matcher<? super T>。从中它将推断出约束T << ObjectT << SomeExceptionObject将在构建最小擦除候选集时被消除。剩下的候选人SomeException(最终:D)将被替换T

到目前为止,我们已经展示了 eclipse 和 JDK7 在这种情况下的正确行为。我认为没有任何方法可以强制 javac 也正常运行。您可以显式声明类型参数或使用 JDK7(将源和目标指定为 6)。

于 2013-03-07T11:59:17.413 回答
1

您应该考虑两件事:

  1. 首先,您可以像这样使用它:CoreMatcher.<SomeException>allOf(...)它将显式设置T.

  2. 其次,由于类型擦除,作为运行时你总是有一个Matcher<Object>. 因此,在任何一种情况下,运行时行为都是相同的。

于 2013-03-07T12:02:21.110 回答