InvocationTargetException 是 Java 反射調用時的包裝異常,它不是真正的錯誤原因,真正的異常藏在 getCause() 裡。
InvocationTargetException (反射調用失敗)
└── cause: 真實異常 (如 NullPointerException、FileNotFoundException、自定義異常等)
setAccessible(true) 未設或 SecurityManager 限制null 實例,實例方法傳錯對象ExceptionInInitializerError 包裹在內try {
Method method = clazz.getMethod("targetMethod", String.class);
method.invoke(instance, "param");
} catch (InvocationTargetException e) {
// 關鍵:打印真實原因
Throwable realCause = e.getCause();
realCause.printStackTrace(); // 這裡才是真正的錯誤堆疊
// 或拋出真實異常便於上層處理
if (realCause instanceof RuntimeException) throw (RuntimeException) realCause;
if (realCause instanceof Error) throw (Error) realCause;
throw new RuntimeException(realCause);
} catch (IllegalAccessException | NoSuchMethodException e) {
// 反射 API 本身的錯誤(權限、方法不存在)
e.printStackTrace();
}
用戶反饋:InvocationTargetException,最終發現是目標方法內讀取配置文件時 FileNotFoundException。堆疊頂層只顯示 InvocationTargetException,展開 Caused by: 才看到 FileNotFoundException: config.properties (系統找不到指定的文件)。
見到 InvocationTargetException,直奔 getCause(),那才是真凶。
永遠不要只看頂層異常類名,**展開完整堆疊、提取 Cause、定位業務代碼行號**,才是解決反射調用異常的正確路徑。