您如何抛出通过反射创建的异常 class 的实例?
How do you throw an instance of an Exception class created through reflection?
我正在尝试创建一个根据您传入的类型抛出异常的函数。
private void myFunc(Class<?> exceptionType) {
...do some work...
throw new exceptionOfTypeExceptionTypePassedIn(newMessage);
}
你能做到吗?
您可以在 Class
对象上使用 newInstance
方法。
首先,throw
语句仅适用于 Throwable
或其子类型的引用表达式。因此,您传递给 throw
的表达式必须具有该类型。您可以通过为 exceptionType
参数提供一个界限来实现这一点。
private void myFunc(Class<? extends Throwable> exceptionType) {
如果您现在想限制 Throwable
子类型的类型,您也可以这样做。
如果是 Exception
,您需要 throws
声明
private void myFunc(Class<? extends Exception> exceptionType) throws Exception {
如果是 RuntimeException
,则不会
private void myFunc(Class<? extends RuntimeException> exceptionType) {
根据您的需要,您实际上可以使该方法通用。它看起来像这样
private <T extends Throwable> void myFunc(Class<T> exceptionType) throws T {
至于实际的反射逻辑,您假设相应的类型有一个可访问的构造函数,该构造函数接受 String
参数。如果没有,Java 将抛出它自己的各种异常。你需要处理这些。
一个潜在的解决方案如下所示(javadoc for Class#getConstructor
, javadoc for Constructor#newInstance
)
private <T extends Throwable> void myFunc(Class<T> exceptionType) throws T {
final String message = "some message";
try {
throw exceptionType.getConstructor(String.class).newInstance(message);
} catch (InstantiationException e) {
e.printStackTrace();
// rethrow
} catch (IllegalAccessException e) {
e.printStackTrace();
// rethrow
} catch (IllegalArgumentException e) {
e.printStackTrace();
// rethrow
} catch (InvocationTargetException e) {
e.printStackTrace();
// rethrow
} catch (NoSuchMethodException e) {
e.printStackTrace();
// rethrow
} catch (SecurityException e) {
e.printStackTrace();
// rethrow
}
}
您显然可以将所有这些异常类型折叠成一个多捕获语句。
请注意,如果您传入的异常类型是现有 catch
语句中提到的异常类型之一,它将被吞没,即。没有扔。您还可以将所有这些添加到自己的 throws
声明中。
private static <T extends Throwable> void myFunc(Class<T> exceptionType) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, T {
final String message = "some message";
throw exceptionType.getConstructor(String.class).newInstance(message);
}
或者重新抛出包裹在RuntimeException
.
中的异常
反射很乱。接受的答案有效,但您的代码将更难遵循。您最好重构代码以避免这种情况。
我正在尝试创建一个根据您传入的类型抛出异常的函数。
private void myFunc(Class<?> exceptionType) {
...do some work...
throw new exceptionOfTypeExceptionTypePassedIn(newMessage);
}
你能做到吗?
您可以在 Class
对象上使用 newInstance
方法。
首先,throw
语句仅适用于 Throwable
或其子类型的引用表达式。因此,您传递给 throw
的表达式必须具有该类型。您可以通过为 exceptionType
参数提供一个界限来实现这一点。
private void myFunc(Class<? extends Throwable> exceptionType) {
如果您现在想限制 Throwable
子类型的类型,您也可以这样做。
如果是 Exception
,您需要 throws
声明
private void myFunc(Class<? extends Exception> exceptionType) throws Exception {
如果是 RuntimeException
,则不会
private void myFunc(Class<? extends RuntimeException> exceptionType) {
根据您的需要,您实际上可以使该方法通用。它看起来像这样
private <T extends Throwable> void myFunc(Class<T> exceptionType) throws T {
至于实际的反射逻辑,您假设相应的类型有一个可访问的构造函数,该构造函数接受 String
参数。如果没有,Java 将抛出它自己的各种异常。你需要处理这些。
一个潜在的解决方案如下所示(javadoc for Class#getConstructor
, javadoc for Constructor#newInstance
)
private <T extends Throwable> void myFunc(Class<T> exceptionType) throws T {
final String message = "some message";
try {
throw exceptionType.getConstructor(String.class).newInstance(message);
} catch (InstantiationException e) {
e.printStackTrace();
// rethrow
} catch (IllegalAccessException e) {
e.printStackTrace();
// rethrow
} catch (IllegalArgumentException e) {
e.printStackTrace();
// rethrow
} catch (InvocationTargetException e) {
e.printStackTrace();
// rethrow
} catch (NoSuchMethodException e) {
e.printStackTrace();
// rethrow
} catch (SecurityException e) {
e.printStackTrace();
// rethrow
}
}
您显然可以将所有这些异常类型折叠成一个多捕获语句。
请注意,如果您传入的异常类型是现有 catch
语句中提到的异常类型之一,它将被吞没,即。没有扔。您还可以将所有这些添加到自己的 throws
声明中。
private static <T extends Throwable> void myFunc(Class<T> exceptionType) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, T {
final String message = "some message";
throw exceptionType.getConstructor(String.class).newInstance(message);
}
或者重新抛出包裹在RuntimeException
.
反射很乱。接受的答案有效,但您的代码将更难遵循。您最好重构代码以避免这种情况。