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
那么如何解决这个问题?
答案 0 :(得分:2)
由于在编译时不知道T,所以不能在这样的catch块中使用它。它根本不是编译器支持的东西,因此是错误。
如果您的目的是验证是否抛出了正确的异常,我建议您修改您的测试代码:
@Test
public void testCheckNotNull() {
try {
ValidationUtility.checkNotNull(null, "valuename", exceptionClass);
} catch (Throwable e) {
assertEquals(exceptionClass, e.getClass());
}
}
答案 1 :(得分: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
。
由于您知道,类型T
表示扩展Throwable
的类,因此可能希望在catch块中使用Throwable
。
} catch (Throwable e) {
答案 2 :(得分: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) {}
}