方法不适用于参数,可能的异常类型擦除问题?

时间:2016-04-13 00:04:20

标签: java generics type-erasure hamcrest

我正在使用Java8,并且我正在尝试编写一个测试助手,它将验证抛出的异常属于特定类型。这是一个有效的初始版本:

private static <E extends Exception> void expectThrow(Callable<Void> callable, Class<E> exceptionClass) {
    try {
        callable.call();
    } catch (Exception e) {
        assertTrue(exceptionClass.isInstance(e));
    }
}

我想做的是用hamcrest matcher替换catch块,以便从失败中获得更多有用的信息:

        assertThat(e, Matchers.isA(exceptionClass));

但这不能编译 - 我得到了这个可爱的错误:The method assertThat(T, Matcher<? super T>) in the type Assert is not applicable for the arguments (Exception, Matcher<E>)

这让我很困惑 - 这应该不行吗?这似乎与以下情况类似,完全正常:

    Integer a = 3;
    assertThat(a, Matchers.isA(Number.class));

在玩了一些之后,以下也有效:

        assertThat((E)e, Matchers.isA(exceptionClass));

虽然这给了我一个有用的“从Exception到E的未经检查的演员”类型安全警告。我知道我不能catch (E e) - 键入擦除和所有...

发生了什么事?如何以一种不错的类型安全方式更新我的测试助手?

1 个答案:

答案 0 :(得分:1)

这似乎是5天前终于修复的long-standing issueisA的签名被破坏了。在Hamcrest的下一个版本提供修复程序之前,在您的项目使用该版本之前,您必须使用

assertThat(e, is(instanceOf(exceptionClass)))