首頁>技術>

https://llchen60.com/Java-集合處理-和-空值處理/

1. Arrays.asList

業務開發當中,我們常常會將原始的陣列轉換為List類資料結構,來繼續展開各種Stream操作

Arrays.asList無法轉換基本型別的陣列,可以使用Arrays.stream來進行轉換Arrays.asList返回的list是不支援增刪操作的,其返回的List是Arrays的內部類ArrayList。內部繼承自AbstractList,沒有覆寫父類的add方法對原始陣列的修改會影響到我們獲得的那個ListArrayList實際上是使用了原始的陣列,因此在使用的時候,最好再使用New ArrayList來實現解耦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層

負責資料訪問實現,一般沒有業務邏輯根據情況來做忽略,降級,或者轉化為一個友好的異常

Service層

負責核心業務邏輯,包括外部服務呼叫,訪問資料庫,快取處理,訊息處理等一般會涉及到資料庫事務,出現異常不適合捕獲,否則事務無法自動回滾

Repository層

負責資訊收集,引數校驗,轉換服務層處理的資料適配前端,輕業務邏輯Controller 捕獲異常,然後需要給使用者友好使用者的提示

框架層面的異常處理

儘量不要在框架層面做異常的自動,統一的處理

框架應當來做兜底工作,如果異常上升到最上層邏輯還是無法處理的話,可以用統一的方式進行異常轉換

@RestControllerAdvice@ExceptionHandler3.2 不要直接生吞異常

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

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

3.3 保留原始的資訊

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

catch (IOException e) {    //只保留了異常訊息,棧沒有記錄    log.error("檔案讀取錯誤, {}", e.getMessage());    throw new RuntimeException("系統忙請稍後再試");}catch (IOException e) {    throw new RuntimeException("系統忙請稍後再試", e);}
3.4 小心finally中的異常 + try with resources

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

@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()

11
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • C#中多執行緒的那點事-async & await