建議 只針對異常的情況才使用異常。

2021-08-21 11:56:27 字數 1219 閱讀 3748

在現代的jvm實現上,基於異常的模式比標準模式要慢得多。在我的機器上對於乙個有100個元素的陣列,基於異常的模式比標準滿了2倍。

基於異常的迴圈模式不僅模糊了**的意圖,降低了他的效能,而且他還不能保證正常工作!如果出現了不相關的bug,這個模式會悄悄地失效,從而掩蓋了這個bug,極大的增加了除錯過程的複雜度。假設迴圈體中的計算過程呼叫乙個方法,這個方法執行了對某個不相關陣列的越界訪問。如果使用合理的迴圈模式,這個bug會產生未**捉的異常,從而導致執行緒立即結束,產生完整的堆疊軌跡。如果使用這個誤導的基於異常的迴圈模式,與這個bug相關的異常將會**捉到,並且被錯誤的解釋為正常的迴圈終止條件。

這個例子的教訓很簡單:顧名思義,異常應該只用於異常的情況下,他們永遠不應該用於正常的控制流。更一般的,應該優先使用標準的、容易理解的模式,而不是那些聲稱可以提供更好效能的、弄巧成拙的方法,即使真的能夠改進效能,面對平台實現的不斷改進,這種模式的效能優勢也不可能一直保持。然而,由這種過渡聰明的模式帶來的微妙的bug,以及維護的痛苦卻依然存在。

這條原則對於api設計也有啟發。設計良好的api不應該強迫他的客戶端為了正常的控制流而使用異常。如果類具有「狀態相關」的方法,即只有在特定的不可預知的條件下才可以被呼叫的方法,這個類往往也應該有乙個單獨的「狀態測試」方法,即指示是否可以呼叫這個狀態的方法。例如iterator介面有乙個「狀態相關」的next方法和相應的狀態測試方法hasnext方法。

另一種提供單獨的狀態測試方法的做法是,如果「狀態相關的」方法被呼叫時,該物件處於不適當的狀態之中,他就會返回乙個可識別的值,比如null。這種方法對於iterator而言並不合適,因為null是next方法的合法返回值。

對於「狀態測試方法」和「可識別的返回值」這兩種做法,有些指導原則可以幫助你在兩者之中做出選擇。如果物件將在缺少外部同步的情況下被併發訪問,或者可被外界改變狀態,使用可被是別的返回值可能是很有必要的,因為在呼叫「狀態測試」方法和呼叫對應「狀態相關」方法的時間間隔之中,物件的狀態有可能會發生改變。如果單獨的「狀態測試」方法必須重複「狀態相關」方法的工作,從效能的角度考慮,就應該使用可被識別的返回值。如果所有其他方面都是等同的,那麼「狀態測試」方法則略優於可被識別的返回值。他提供了更好的可讀性,對於使用不當的情形,可能更加易於檢測和改正:如果忘了去呼叫狀態測試方法,狀態相關的方法就會丟擲異常,使這個bug變得很明顯;如果忘了去檢查可識別的返回值,這個bug就很難會被發現。

總而言之,異常是為了在異常情況下使用而設計的。不要將他們用於普通的控制流,也不要編寫迫使他們這麼做的api。

使用異常機制的建議

color red 1 異常處理不能代替簡單測試 color 只在異常情況下使用異常機制 color red 2 不要過分細化異常 color 這樣會使 量急劇的澎漲 color red 3 利用異常層次結構 color 不要只丟擲runtimeexception 或者throwable異常,否則 ...

6 異常釋放鎖的情況

異常釋放鎖的情況對於web程式,異常的釋放鎖,很可能意味著程式出現了錯誤,業務邏輯產生了錯誤的結果導致了嚴重的錯誤,比如 乙個佇列10個任務,很多物件都會去等待第1個佇列正常秩序產生的結果返回再次釋放鎖,那麼其中乙個發生了異常,導致業務沒執行完畢,就釋放鎖的資源。package demo1 crea...

Android空指標異常的常見情況

把我經常遇到的nullpoitexception寫在這裡,以便以後自己查詢原因。1.用findviewbyid param 的方法獲取乙個view物件的時候,有的時候其實應該是獲取乙個layout物件,但是param寫成了乙個r.id.而應該寫成r.layout.yyy的形式。這種情況導致獲取不到想...