Java 集合處理/ 空值處理/ 異常處理,使用心得分享!

Java技術棧

www.javastack.cn

關注閱讀更多優質文章



1. Arrays.asList

業務開發當中,我們常常會將原始的數組轉換爲List類數據結構,來繼續展開各種Stream操作

2. 空值處理

2.1 NullPointerException

  • 可能出現的場景

    • 參數值是Integer等包裝類型,使用時因爲自動拆箱出現了空指針異常
    • 字符串比較
    • ConcurrentHashMap這種容器不支持Key和Value爲null,強行put null的key或Value會出現空指針異常
    • 方法或遠程服務返回的list是null,沒做判空就直接調用,出現空指針異常
    • 聯級調用的null check
  • best practice

    • string.equalsTo(variableName)
    • Optional.ofNullable()
    • orElse()

3. 異常處理

3.1 在業務代碼層面考慮異常處理

  • 大多數業務應用都採用三層架構
    • 負責數據訪問實現,一般沒有業務邏輯
    • 根據情況來做忽略,降級,或者轉化爲一個友好的異常
    • 負責核心業務邏輯,包括外部服務調用,訪問數據庫,緩存處理,消息處理等
    • 一般會涉及到數據庫事務,出現異常不適合捕獲,否則事務無法自動回滾
    • 負責信息收集,參數校驗,轉換服務層處理的數據適配前端,輕業務邏輯
    • Controller 捕獲異常,然後需要給用戶友好用戶的提示
    • Controller層
    • Service層
    • Repository層
  • 框架層面的異常處理
    • @RestControllerAdvice
    • @ExceptionHandler
    • 儘量不要在框架層面做異常的自動,統一的處理
    • 框架應當來做兜底工作,如果異常上升到最上層邏輯還是無法處理的話,可以用統一的方式進行異常轉換

3.2 不要直接生吞異常

捕獲了異常以後不應該生吞,因爲吞掉的異常如果沒有正常處理的話,出現Bug會很難發現。

需要有合適的轉化成用戶友好的異常,或者至少在warn, error級別來做log。

推薦閱讀:10 個深惡痛絕的 Java 異常。

3.3 保留原始的信息

在捕捉了異常之後,一定要記得在log 或者在向外扔出的異常之中記錄原始異常信息

catch (IOException e) {
    //只保留了異常消息,棧沒有記錄
    log.error("文件讀取錯誤, {}", e.getMessage());
    throw new RuntimeException("系統忙請稍後再試");
}


catch (IOException e) {
    throw new RuntimeException("系統忙請稍後再試", e);
}

另外,關注公衆號Java技術棧,在後臺回覆:面試,可以獲取我整理的 Java 系列面試題和答案,非常齊全。

3.4 小心finally中的異常 + try with resources

注意在資源釋放處理等收尾操作的時候也可能會出現異常,這種時候,如果try block邏輯和finnally邏輯都有異常拋出的話,try當中的異常會被finnally中的異常覆蓋掉,這會讓問題變得非常不明顯。

推薦閱讀:你還在使用 try-catch-finally 關閉資源?

@GetMapping("wrong")
public void wrong() {
    try {
        log.info("try");
        //異常丟失
        throw new RuntimeException("try");
    } finally {
        log.info("finally");
        throw new RuntimeException("finally");
    }
}

對於實現了AutoCloseable接口的資源,可以使用try-with-resources來釋放資源,就是在try中帶資源的聲明。

try catch finally vs try with resources

Scanner scanner = null;
try {
    scanner = new Scanner(new File("test.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}

3.5 線程池任務的異常處理

設置自定義的異常處理程序作爲保底,比如在聲明線程池時自定義線程池的未捕獲異常處理程序:

new ThreadFactoryBuilder()
  .setNameFormat(prefix+"%d")
  .setUncaughtExceptionHandler((thread, throwable)-> log.error("ThreadPool {} got exception", thread, throwable))
  .get()

最後,關注公衆號Java技術棧,在後臺回覆:面試,可以獲取我整理的 Java 系列面試題和答案,非常齊全。

Reference

  1. https://www.baeldung.com/java-try-with-resources
  2. https://time.geekbang.org/column/article/220230






關注Java技術棧看更多幹貨



戳原文,獲取精選面試題!

本文分享自微信公衆號 - Java技術棧(javastack)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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