Java反射中如何捕获特定异常CannotDoThisException?
如何通过反射捕获目标方法抛出的检查型异常?
我太懂这种坑了!你写了个带检查型异常的静态方法,想用反射调用的时候,直接catch原异常居然被编译器说代码不可达,确实挺让人懵的。先看看你的代码场景:
首先是定义了异常的Foo类:
class Foo { public static void doThis() throws CannotDoThisException { // do something } }
然后是你用反射调用的Bar类:
public class Bar { Class c = Class.forName("Foo"); Method m = c.getDeclaredMethod("doThis",null); try { m.invoke(null,null); } catch (CannotDoThisException e) { // Compiler says this is unreachable block. } }
为啥编译器说这个catch块不可达?
核心原因是:反射的Method.invoke()方法不会直接抛出目标方法的原始异常。当目标方法抛出CannotDoThisException时,invoke方法会把这个异常包装成InvocationTargetException(这是一个受检异常)抛出来,而不是直接抛出原异常。所以编译器能分析出,你的代码里永远不会走到catch (CannotDoThisException)这个分支,自然提示不可达。
怎么才能捕获到目标异常?
你需要先捕获InvocationTargetException,然后通过它的getTargetException()方法拿到被包装的原始异常,再判断类型后处理。修改后的代码大概是这样:
public class Bar { public static void main(String[] args) { try { Class<?> c = Class.forName("Foo"); Method m = c.getDeclaredMethod("doThis", null); m.invoke(null, null); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { // 处理反射过程中出现的异常,比如找不到类、方法,或者权限问题 e.printStackTrace(); } catch (InvocationTargetException e) { // 提取目标方法抛出的原始异常 Throwable originalException = e.getTargetException(); if (originalException instanceof CannotDoThisException) { // 这里就是你要捕获的目标异常啦 CannotDoThisException ex = (CannotDoThisException) originalException; // 写你的异常处理逻辑 System.out.println("成功捕获到CannotDoThisException:" + ex.getMessage()); } else { // 如果是目标方法抛出的其他异常,也可以在这里处理 originalException.printStackTrace(); } } } }
额外提醒
getTargetException()返回的是Throwable类型,一定要先做类型判断再强转,避免ClassCastException。- 反射过程中还可能抛出
ClassNotFoundException、NoSuchMethodException这些异常,记得也要一起处理或者声明抛出。
内容的提问来源于stack exchange,提问作者Shuyou
相关产品推荐
相关产品推荐

