Android基礎進階之EffectiveJava翻譯系列(第八章:異
高效使用異常指南
Item 57: Use exceptions only for exceptional conditions
只有在異常條件下才使用異常
考慮如下的程式碼
//bad !! don't do thistry { int i = 0; while(true) range[i++].climb(); } catch(ArrayIndexOutOfBoundsException e){}
使用異常條件來終止遍歷操作是非常錯誤的做法
使用如下程式碼代替
for (Mountain m : range) m.climb();
名副其實,異常只能用在異常條件下,而不能用於流程控制
Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
對可恢復條件使用檢查異常,對程式錯誤使用執行時異常。
Java提供了三種異常:checked exceptions,runtime exceptions and errors.大多數程式設計師對何時使用何種異常有困惑,有如下幾種原則作參考
決定使用檢查異常或非檢查異常的原則是:呼叫方可以合理的修復異常,現如今的IDE工具如eclipse或Android studio會自動提示此類異常,自動填充try catch
非檢查異常有兩種:runtime exceptions and errors
用執行時異常(runtime exceptions)識程式錯誤,絕大多數的執行時異常都表明違反了某種前提條件,如ArrayIn�dexOutOfBoundsException陣列越界
有一個普遍的約定是error用於JVM,所以所有的非檢查異常都應該繼承自 RuntimeException
常見的非檢查異常runtime exception
NullPointerException, 空指標異常
ArithmeticException, 算術異常
ClassCastException, 型別強制轉換異常
IllegalArgumentException, 傳遞非法引數異常
Item 59: Avoid unnecessary use of checked exceptions
避免過度使用檢查異常
如果一個方法有多個檢查異常,呼叫者會包裹多個catch來處理異常,這裡沒有一個絕對的準則,可以使用if語句把條件先過濾一遍而避免拋異常
Item 60: Favor the use of standard exceptions
使用常用異常
當需要丟擲一個異常時,儘量使用Java平臺提供好的異常,因為大家都知道什麼意思
Item 61: Throw exceptions appropriate to the abstraction
丟擲更合適的抽象異常
當丟擲和任務不相關的異常時容易讓人困惑,當丟擲一個低階的異常時,這種情況經常發生,它不僅僅令人困惑,也汙染了上層的呼叫
為了避免這個問題,上層應該捕獲較低階別的異常,並在它們的位置上丟擲可以用更高階別的抽象來解釋的異常,如:
// Exception Translationtry { // Use lower-level abstraction to do our bidding ... } catch(LowerLevelException e) { throw new HigherLevelException(...); }
更具體的例子在List<E>的方法中
/** * Returns the element at the specified position in this list. * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}). */public E get(int index) { ListIterator<E> i = listIterator(index); try { return i.next(); } catch(NoSuchElementException e) { throw new IndexOutOfBoundsException("Index: " + index); } }
這種特殊的異常處理方式被稱為"異常鏈",但是也不應該過度使用
我們也可以在在上層呼叫中丟擲底層錯誤的原因
// Exception Chainingtry { ... // Use lower-level abstraction to do our bidding} catch (LowerLevelException cause) { throw new HigherLevelException(cause); }
最好的方式還是儘量在底層避免異常,如果不能處理在考慮"異常鏈"的方式
Item 62: Document all exceptions thrown by each method
為每個方法丟擲的異常新增文件註釋
對於檢查異常,要說明前置條件,並用@throws標記合適的異常,不要為了圖簡單直接 @throws Exception
如果一個異常被多個方法丟擲,並且是相同的原因,則不要在方法上註釋,而是要在類上新增異常註釋
Item 63: Include failure-capture information in detail messages
列印出異常的詳細資訊以便於分析
Item 64: Strive for failure atomicity
保證錯誤的原子性(呼叫一千次,輸出一樣)
即使一個異常發生了,我們也希望物件能正常使用
有幾種方式可以達到這一點,最簡單的就是建立不可變的物件,如果一個物件是不可變的,原子性也隨之而來
對於可變物件,常見的方式是檢查引數的合法性(Item 38)
第三種方式是發生異常後,回滾異常狀態為使用前的初始狀態
最後一種方式使用複製來避免發生錯誤時改變原來物件的狀態,如Collections.sort,排序方法會先轉成array陣列來排序,本來是為了提高效能,額外的如果發生了錯誤不會改變原集合的狀態
雖然原子效能保證,但是實際使用中並不總是能達到滿意的狀態,如兩個執行緒同時修改一個物件,沒有同步的情況下,引發了currentModificationException.這時如果恢復物件的狀態依然不能使程式正確執行
作為一種規則來講,當發生異常時總能確保當前物件的狀態,可惜目前很多API都沒有遵守
Item 65: Don’t ignore exceptions
不要忽略異常
這條建議看似很明顯,但是值得重複,當API的設計者宣告瞭一種異常,他們是為了告訴你什麼,不要忽略它!很容易包裹一個空的try catch語句就不管這個異常了.如:
try { ... } catch (SomeException e) { }
空處理並不是拋異常的初衷,目的是為了強制解決這個異常條件.忽略異常就像忽略火警廣播,有人關了廣播導致其他人並不知道發生了火災.如果確實需要一個空的處理,需要詳細說明為何空處理是合適的
作者:青樓愛小生
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2325/viewspace-2821962/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Serilog文件翻譯系列(三) - 基礎配置
- JavaSE基礎系列之異常Java
- 【Android 進階】仿抖音系列之翻頁上下滑切換視訊(一)Android
- 前端基礎之jQuery進階前端jQuery
- Gradle系列之Android Gradle基礎配置GradleAndroid
- [翻譯]理解 HTTP 基礎HTTP
- 【翻譯】ANDROID KTX – 使用Kotlin進行Android開發AndroidKotlin
- Android 進階 ———— Handler系列之建立子執行緒HandlerAndroid執行緒
- <<Modern CMake>> 翻譯 2. CMake 基礎
- Android進階:十四、熟悉Android打包編譯的流程Android編譯
- [一天一個進階系列] - MyBatis基礎篇MyBatis
- Python的基礎進階Python
- Android 基礎之 HandlerAndroid
- 【Android進階】RecyclerView之ItemDecoration(一)AndroidView
- Android自我進階——JAVA之JVMAndroidJavaJVM
- Draft 文件翻譯 - 快速開始 - 基礎APIRaftAPI
- Android進階;App的異常崩潰處理AndroidAPP
- 【Go進階—基礎特性】反射Go反射
- 【Go進階—基礎特性】deferGo
- 【Go進階—基礎特性】介面Go
- Pandas進階貳 pandas基礎
- 【Android進階】RecyclerView之快取(二)AndroidView快取
- Android 布 局 翻 譯 器Android
- TypeScript 官方手冊翻譯計劃【一】:基礎TypeScript
- ASM 翻譯系列第十一彈:高階知識 Offline or drop?ASM
- python 基礎之異常處理Python
- SpringCloud基礎教程(三)-Eureka進階SpringGCCloud
- 【Go進階—基礎特性】錯誤Go
- 前端工程基礎知識點--Browserslist (基於官方文件翻譯)前端
- 前端工程基礎知識點–Browserslist (基於官方文件翻譯)前端
- Android基礎之Activity全解析Android
- TailWind文件翻譯說明以及每日翻譯進度AI
- 【Android進階】RecyclerView之繪製流程(三)AndroidView
- Vue 系列一 之 Vue 基礎Vue
- Pytorch系列之常用基礎操作PyTorch
- Kotlin(android)協程中文翻譯KotlinAndroid
- ASM 翻譯系列第十三彈:ASM 高階知識 - Forcing the issueASM
- Python 使用白嫖網易翻譯 API 進行翻譯PythonAPI