给出以下示例(使用JUnit与Hamcrest匹配器):
Map> expected = null;
Map> result = null;
assertThat(result, is(expected));
这不会使用JUnit assertThat方法签名来编译:
public static void assertThat(T actual, Matcher matcher)
编译器错误消息是:
Error:Error:line (102)cannot find symbol method
assertThat(java.util.Map>,
org.hamcrest.Matcher
extends java.io.Serializable>>>)
但是,如果我将assertThat方法签名更改为:
public static void assertThat(T result, Matcher extends T> matcher)
然后编译工作。
所以三个问题:
>为什么当前版本没有编译?虽然我模糊地理解这里的协方差问题,但我肯定不能解释它,如果我不得不。
>将assertThat方法更改为Matcher有没有其他情况下会打破,如果你这样做?
>有没有任何点在JUnit中assertThat方法的泛化? Matcher类似乎不需要它,因为JUnit调用了matches方法,它没有任何通用类型,并且只是看起来像一个尝试强制类型安全,不做任何事情,因为匹配器将不会实际上匹配,并且测试将失败。没有不安全的操作涉及(或者似乎)。
作为参考,这里是assertThat的JUnit实现:
public static void assertThat(T actual, Matcher matcher) {
assertThat("", actual, matcher);
}
public static void assertThat(String reason, T actual, Matcher matcher) {
if (!matcher.matches(actual)) {
Description description = new StringDescription();
description.appendText(reason);
description.appendText("\nExpected: ");
matcher.describeTo(description);
description
.appendText("\n got: ")
.appendValue(actual)
.appendText("\n");
throw new java.lang.AssertionError(description.toString());
}
}