0

的java代码:

public static <T extends Throwable> void checkNotNull(Object value, String name, Class<T> exceptionClass) throws T, SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
    if (value==null)
      throw ExceptionHelper.constructException(exceptionClass, name + " should not be null");
}

static <T extends Throwable> T constructException(java.lang.Class<T> exceptionClass, String message) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
    Constructor<T> constructor = exceptionClass.getConstructor(String.class);
    T result = constructor.newInstance(message);
    return result;
}

junit代码:

@Test
public void testCheckNotNull() {
    try {
    ValidationUtility.checkNotNull(null, "valuename", exceptionClass);
    } catch (T e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
      } 
}

然后编译器说:不能在catch块中使用类型参数T

那么如何解决这个问题呢?

4

3 回答 3

2

由于 T 在编译时是未知的,因此您不能在这样的 catch 块中使用它。它根本不是编译器支持的东西,因此会出现错误。

如果您的意图是验证是否引发了正确的异常,我建议您修改您的测试代码,如下所示:

@Test
public void testCheckNotNull() {
    try {
        ValidationUtility.checkNotNull(null, "valuename", exceptionClass);
    } catch (Throwable e) {
        assertEquals(exceptionClass, e.getClass());
    } 
}
于 2012-10-05T14:50:01.673 回答
0

经过

Constructor<T> constructor = exceptionClass.getConstructor(String.class);
T result = constructor.newInstance(message);

您正在创建作为参数传递的类的结果对象。这里使用'T',仅表示您正在使用扩展类构造结果Throwable

在测试方法中,即使这样声明它:

    @Test
    public <T extends Throwable> void testCheckNotNull() {
        try {
        ValidationUtility.checkNotNull(null, "valuename", exceptionClass);
        } catch (T e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
          } 
    }

仍然T是一种类型,而不是Exception可以被捕获的类。正如您在错误中发现的那样,您将无法捕获Type.

既然你知道, TypeT代表类扩展Throwable, use 可能想Throwable在 catch 块中使用。

        } catch (Throwable e) {
于 2012-10-05T14:46:24.183 回答
0

如前面的答案中所述,您无法捕获 T。这是因为擦除。如果您期望出现异常,我建议使用 JUnit4。

@Test(expected = Throwable.class)
public void testCheckNotNull() throws Throwable {
     ValidationUtility.checkNotNull(null, "valuename", exceptionClass);
}

您的测试代码也存在错误。如果没有抛出异常,那么测试仍然会通过。你也需要失败

@Test
public void testCheckNotNull() {
    try {
      ValidationUtility.checkNotNull(null, "valuename", exceptionClass);
      fail("expected to throw")
    } catch (Throwable e) {}
}
于 2012-10-05T15:02:53.743 回答