Exception vs Error
一個形象的比喻
假如你開車上山楼誓,車壞了把兔,你拿出工具箱修一修,修好繼續(xù)上路(Exception被捕獲瓮顽,從異常中恢復县好,繼續(xù)程序的運行),車壞了暖混,你不知道怎么修缕贡,打電話告訴修車行,告訴你是什么問題拣播,要車行過來修晾咪。(在當前的邏輯背景下,你不知道是怎么樣的處理邏輯贮配,把異常拋出去到更高的業(yè)務層來處理)谍倦。你打電話的時候,要盡量具體牧嫉,不能只說我車動不了了剂跟。那修車行很難定位你的問題。(要補貨特定的異常酣藻,不能捕獲類似Exception的通用異常)曹洽。還有一種情況是,你開車上山辽剧,山塌了送淆,這你還能修嗎?(Error:導致你的運行環(huán)境進入不正常的狀態(tài)怕轿,很難恢復)
NoClassDefFoundError 與 ClassNotFoundException 區(qū)別
- NoClassDefFoundError -> Error 會導致程序處于非正常狀態(tài)偷崩,不可捕獲
- ClassNotFoundException -> Exception 可捕獲,編譯期可檢查Exception,需要顯示的捕獲(補充:Exception 分為(在編譯期)可檢查和不可檢查的Exception撞羽,編譯期可檢查Exception,需要顯示的捕獲阐斜;編譯期不可檢查的Exception就是所謂的運行時異常(RuntimeException: NullPointException),需要根據具體情況進行捕獲處理)
throw诀紊、throws 關鍵字
- throw 拋出一個異常谒出,寫在方法body體中,修飾一個異常實例
- throws 定義一個異常,類似try-catch-throw,寫在方法簽名/類名之后邻奠,修飾方法/類
try-catch-finally
異常捕獲需要注意
- 盡量不要捕獲類似Exception的通用異常笤喳,應該捕獲特定異常
- 不要生吞異常,發(fā)生異常的時候碌宴,盡量提供更多異常cause信息并記錄到日志中杀狡,盡量不要輸出全部堆棧信息到console中,這樣做不僅影響程序性能而且在復雜系統中很難定位問題
自定異常需要注意
- 是否要定義成Checked Exception ( eg : IOException), 這種異常的設計初衷是為了從異常情況中恢復贰镣,設計者應該有足夠的信息對異常進行分類
- 信息安全: 在保證診斷信息足夠的同時呜象,需要避免包含敏感信息膳凝,避免潛在的安全問題。(eg: java.net.ConnectException 的出錯信息Connection refused (Connection refused)并不包含具體的機器名恭陡,IP鸠项,密碼等)
性能角度看Java異常處理機制
- try-catch代碼塊會影響JVM對代碼進行優(yōu)化,所以會產生額外的性能開銷子姜,建議僅捕獲有不要的代碼段,不要一個try包住整段代碼楼入。此外哥捕,不要用try-catch來控制程序流程,因為它遠比條件語句 (if-else /switch) 要低效
- Java 每實例化一個Exception都需要對當前的棧進行快照嘉熊,這是一個比較重的操作遥赚,如果發(fā)生頻繁,這個開銷就不能被忽略了