Java 集合處理/ 空值處理/ 異常處理,使用心得分享!
1. Arrays.asList
業(yè)務(wù)開發(fā)當(dāng)中,我們常常會(huì)將原始的數(shù)組轉(zhuǎn)換為List類數(shù)據(jù)結(jié)構(gòu),來繼續(xù)展開各種Stream操作
Arrays.asList無法轉(zhuǎn)換基本類型的數(shù)組,可以使用Arrays.stream來進(jìn)行轉(zhuǎn)換 Arrays.asList返回的list是不支持增刪操作的,其返回的List是Arrays的內(nèi)部類ArrayList。內(nèi)部繼承自AbstractList,沒有覆寫父類的add方法 對原始數(shù)組的修改會(huì)影響到我們獲得的那個(gè)List ArrayList實(shí)際上是使用了原始的數(shù)組,因此在使用的時(shí)候,最好再使用New ArrayList來實(shí)現(xiàn)解耦
2. 空值處理
2.1 NullPointerException
可能出現(xiàn)的場景
參數(shù)值是Integer等包裝類型,使用時(shí)因?yàn)樽詣?dòng)拆箱出現(xiàn)了空指針異常 字符串比較 ConcurrentHashMap這種容器不支持Key和Value為null,強(qiáng)行put null的key或Value會(huì)出現(xiàn)空指針異常 方法或遠(yuǎn)程服務(wù)返回的list是null,沒做判空就直接調(diào)用,出現(xiàn)空指針異常 聯(lián)級(jí)調(diào)用的null check best practice
string.equalsTo(variableName)Optional.ofNullable()orElse()
3. 異常處理
3.1 在業(yè)務(wù)代碼層面考慮異常處理
大多數(shù)業(yè)務(wù)應(yīng)用都采用三層架構(gòu) 負(fù)責(zé)數(shù)據(jù)訪問實(shí)現(xiàn),一般沒有業(yè)務(wù)邏輯 根據(jù)情況來做忽略,降級(jí),或者轉(zhuǎn)化為一個(gè)友好的異常 負(fù)責(zé)核心業(yè)務(wù)邏輯,包括外部服務(wù)調(diào)用,訪問數(shù)據(jù)庫,緩存處理,消息處理等 一般會(huì)涉及到數(shù)據(jù)庫事務(wù),出現(xiàn)異常不適合捕獲,否則事務(wù)無法自動(dòng)回滾 負(fù)責(zé)信息收集,參數(shù)校驗(yàn),轉(zhuǎn)換服務(wù)層處理的數(shù)據(jù)適配前端,輕業(yè)務(wù)邏輯 Controller 捕獲異常,然后需要給用戶友好用戶的提示 Controller層 Service層 Repository層 框架層面的異常處理 @RestControllerAdvice@ExceptionHandler盡量不要在框架層面做異常的自動(dòng),統(tǒng)一的處理 框架應(yīng)當(dāng)來做兜底工作,如果異常上升到最上層邏輯還是無法處理的話,可以用統(tǒng)一的方式進(jìn)行異常轉(zhuǎn)換
3.2 不要直接生吞異常
捕獲了異常以后不應(yīng)該生吞,因?yàn)橥痰舻漠惓H绻麤]有正常處理的話,出現(xiàn)Bug會(huì)很難發(fā)現(xiàn)。
需要有合適的轉(zhuǎn)化成用戶友好的異常,或者至少在warn, error級(jí)別來做log。
3.3 保留原始的信息
在捕捉了異常之后,一定要記得在log 或者在向外扔出的異常之中記錄原始異常信息
catch?(IOException?e)?{
????//只保留了異常消息,棧沒有記錄
????log.error("文件讀取錯(cuò)誤,?{}",?e.getMessage());
????throw?new?RuntimeException("系統(tǒng)忙請稍后再試");
}
catch?(IOException?e)?{
????throw?new?RuntimeException("系統(tǒng)忙請稍后再試",?e);
}3.4 小心finally中的異常 + try with resources
注意在資源釋放處理等收尾操作的時(shí)候也可能會(huì)出現(xiàn)異常,這種時(shí)候,如果try block邏輯和finnally邏輯都有異常拋出的話,try當(dāng)中的異常會(huì)被finnally中的異常覆蓋掉,這會(huì)讓問題變得非常不明顯。
@GetMapping("wrong")
public?void?wrong()?{
????try?{
????????log.info("try");
????????//異常丟失
????????throw?new?RuntimeException("try");
????}?finally?{
????????log.info("finally");
????????throw?new?RuntimeException("finally");
????}
}
對于實(shí)現(xiàn)了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 線程池任務(wù)的異常處理
設(shè)置自定義的異常處理程序作為保底,比如在聲明線程池時(shí)自定義線程池的未捕獲異常處理程序:
new?ThreadFactoryBuilder()
??.setNameFormat(prefix+"%d")
??.setUncaughtExceptionHandler((thread,?throwable)->?log.error("ThreadPool?{}?got?exception",?thread,?throwable))
??.get()
Reference
https://www.baeldung.com/java-try-with-resources https://time.geekbang.org/column/article/220230
后臺(tái)回復(fù)?學(xué)習(xí)資料?領(lǐng)取學(xué)習(xí)視頻
如有收獲,點(diǎn)個(gè)在看,誠摯感謝
評論
圖片
表情
