Java自定義異常輸出

要理解Java異常處理是如何工作的,你需要掌握以下三種類型的異常:

  • 檢查性異常:
    最具代表的檢查性異常是用戶錯誤或問題引起的異常,這是程序員無法預見的。例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單地忽略。
  • 運行時異常:
    運行時異常是可能被程序員避免的異常。與檢查性異常相反,運行時異常可以在編譯時被忽略。
  • 錯誤:
    錯誤不是異常,而是脫離程序員控制的問題。錯誤在代碼中通常被忽略。例如,當棧溢出時,一個錯誤就發生了,它們在編譯也檢查不到的。

一.Exception 類的層次

在這裏插入圖片描述

從繼承關係可知:Throwable是異常體系的根,它繼承自Object。Throwable有兩個體系:Error和Exception,Error表示嚴重的錯誤,程序對此一般無能爲力,例如:
1.OutOfMemoryError:內存耗盡
2.NoClassDefFoundError:無法加載某個Class
3.StackOverflowError:棧溢出

而Exception則是運行時的錯誤,它可以被捕獲並處理。某些異常是應用程序邏輯處理的一部分,應該捕獲並處理。例如:
1.NumberFormatException:數值類型的格式錯誤
2.FileNotFoundException:未找到文件
3.SocketException:讀取網絡失敗
還有一些異常是程序邏輯編寫不對造成的,應該修復程序本身。例如:
1.NullPointerException:對某個null的對象調用方法或字段
2.IndexOutOfBoundsException:數組索引越界
Exception又分爲兩大類:
1.RuntimeException以及它的子類;
2.非RuntimeException(包括IOExceptionReflectiveOperationException等等)
Java規定:
必須捕獲的異常,包括Exception及其子類,但不包括RuntimeException及其子類,這種類型的異常稱爲Checked Exception。

不需要捕獲的異常,包括Error及其子類,RuntimeException及其子類。

二.捕獲異常

捕獲異常使用try…catch語句,把可能發生異常的代碼放到try {…}中,然後使用catch捕獲對應的Exception及其子類

 try {
   Integer.valueOf("22m");
 } catch (NumberFormatException e) {
   e.printStackTrace();
 }

在異常捕獲的同時,我們希望同時輸出異常的詳細信息,大多數情況下會選擇e.printStackTrace(); 這個方法,但是他對於系統 的性能會有一定的影響,先不說開銷的問題,有些時候我們需要做一些自定義的輸出,與log系統進行結合,可是e.printStackTrace(); 並沒有返回值,這就很尷尬,接下來我們自定義異常收集器

三.自定義異常收集器

3.1 定義log輸出的模板

設計的理念:
1.我們採用模板的設計模式定義接口,如果小夥伴對模板模式不了接,請看這篇文章https://blog.csdn.net/weixin_38937840/article/details/104211816
2.我們獲取堆裏的異常信息(當然獲取Throwable ,Exception也是可以),源碼在文末會提供

public abstract class LogTemplate {
    /**前綴*/
    protected static final String PREFIX = "Java有貨";
    /**鏈接符*/
    protected static final String JOINER = "-----";

    /**
     * <p>
     *       自定義前綴輸出
     * </p>
     * /
    protected abstract void logError(String prefix,StackTraceElement[] stackTrace);

    /**
     * <p>
     *       默認前綴統一輸出
     * </p>
     */
    protected abstract void logError(StackTraceElement[] stackTrace);

//    protected abstract void logError(String prefix, Exception e);
//    protected abstract void logError(Exception e);
//    protected abstract void logError(String prefix, Throwable e);
//    protected abstract void logError(Throwable e);


    protected boolean verify(String prefix){
        boolean blank = StringUtils.isEmpty(prefix);
        return blank;
    }

    /**
     *       統一日誌出口
     */
    public void logPrint(String prefix, StackTraceElement[] stackTrace){
        boolean verify = verify(prefix);
        if (verify){
            logError(stackTrace);
        }else {
            logError(prefix,stackTrace);
        }
    }

3.2 實現自定義輸出

@Slf4j
public class LogError extends LogTemplate {
    @Autowired(required = false)
    private TaskExecutor taskExecutor;
    private static final String MSG = " 錯誤詳細信息 : ";
    /**
     * <p>
     *       錯誤日誌記錄
     * </p>
     */
    @Override
    protected void logError(String prefix,StackTraceElement[] stackTrace) {
        log(prefix ,stackTrace );
    }

    /**
     * <p>
     *       錯誤日誌記錄
     * </p>
     */
    @Override
    protected void logError(StackTraceElement[] stackTrace) {
        log(stackTrace);
    }


    /**
     * <p>
     *       錯誤日誌記錄,內部輸出
     * </p>
     */
    private void log(String prefix,StackTraceElement[] stackTrace){
        CompletableFuture.runAsync(() -> {
            for (StackTraceElement stackTraceElement : stackTrace) {
                log.error(PREFIX + JOINER + prefix.trim() + JOINER + "{}",MSG+ stackTraceElement.toString());
            }
        },taskExecutor);

    }

    /**
     * <p>
     *       錯誤日誌記錄,內部輸出
     * </p>
     */
    private void log(StackTraceElement[] stackTrace){
        CompletableFuture.runAsync(() -> {
            for (StackTraceElement stackTraceElement : stackTrace) {
                log.error(PREFIX  + "{}", JOINER +MSG+ stackTraceElement);
            }
        },taskExecutor);
    }
}

這裏使用了CompletableFuture,如果不瞭解的同學,請看下面的文章
https://blog.csdn.net/weixin_38937840/article/details/105046588

3.3 使用驗證

 try {
   Integer.valueOf("22m");
 } catch (NumberFormatException e) {
   logError.logPrint("swagger",e.getStackTrace());
 }

如下圖,這時我們就可以與業務場景進行高度結合,快速定位
在這裏插入圖片描述
源碼地址:https://github.com/Dylan-haiji/javayh-platform/tree/master/javayh-starter/javayh-log-starter/src/main/java/com/javayh/log/log
本文的分享暫時就到這裏,希望對您有所幫助
關注 Java有貨領取更多資料

聯繫小編。微信:372787553,帶您進羣互相學習
左側小編微信,右側獲取免費資料
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章