InvocationTargetException的產(chǎn)生與處理

開發(fā)中 我們 需要對 異常 進行 捕獲處理。
某些地方 會 對異常進行全局 攔截處理,時常遇到 的 問題是,異常"迷路"了。
沒有根據(jù)設(shè)定 ,被特定的異常處理器進行處理,如:
業(yè)務(wù)下層定義了 一個 UserException。
經(jīng)過層層調(diào)用,系統(tǒng)最上層 希望 統(tǒng)一捕獲UserException 進行全局處理,但是層層 調(diào)用后,原本的UserException無法 通過 catch(UserException e) 捕獲了。

很常見的一個的 原因 就 是 被“”了。被InvocationTargetException 吃了。
我們時常使用的 包括 spring在內(nèi)的 高級 框架 會 在方法調(diào)用的時候,進行"加料",方法不一定是簡單的直接調(diào)用執(zhí)行,方法 可能 被 通過 反射 執(zhí)行。

示例代碼如下

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class TestException extends Exception {

    TestException(String s) {
        super(s);
    }
}

class Reflected {

    public void run(int i) throws TestException {
        if (i < 0) {
            throw new TestException("涼涼");
        }
        System.out.println("參數(shù):" + i);
    }
}

/**
 * @author dongbin
 */
public class ReflectTest {

    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("cn.qingtui.Reflected");
            Method method = clazz.getMethod("run", int.class);
            method.invoke(clazz.newInstance(), -1);
        } catch (InvocationTargetException e) {
            System.out.println("此處接收被調(diào)用方法內(nèi)部未被捕獲的異常");
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

輸出結(jié)果 如下

此處接收被調(diào)用方法內(nèi)部未被捕獲的異常
此處接收被調(diào)用方法內(nèi)部未被捕獲的異常
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at im.qingtui.app.tms.ReflectTest.main(ReflectTest.java:32)
Caused by: im.qingtui.app.tms.TestException: 涼涼
    at cn.qingtui.Reflected.run(ReflectTest.java:17)
    ... 5 more

catch的時候 會走到 catch (InvocationTargetException e) 分支 。
可能的想法 是 ,我 直接 catch(TestException e) 能捕獲到嗎?

答: 編譯不過,因為 try的代碼塊里 沒有 任何地方 throw TestException,所以不能catch

image.png

解決辦法
從異常的 堆棧信息可知,原本要拋出的 異常會被InvocationTargetException“吃”進了肚子里,信息會被保留。
開發(fā)的 時候 記得,如果方法 被 反射執(zhí)行了,那異常處理的時候,則 需要 使用
InvocationTargetException.getTarget()
拿到原始異常,再進行處理。
需要注意的 是 InvocationTargetException.getTarget()的返回類型是 Throwable。
換句話說,你get到以后 不能 直接 知道 異常的 類型,需要寫 一系列的 判斷 代碼 來 識別 里面的內(nèi)容 具體是 什么異常。

比較 常見的 尷尬局面 是 ,下層 業(yè)務(wù) 拋出的 gezho0ng1異常 ,最后 都變成了 InvocationTargetException。
上層需要 挨個 if else 判斷(不能 switch case),具體要對 異常 如何 處理。

面對這種局面,如何 優(yōu)雅的 處理?歡迎 各位 大佬 評論區(qū)留言。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容