Checked and Unchecked Exception in Java


理解錯誤才能錯得不糊塗、錯得到位、錯得妙!

如何看出工程師的底子瞧瞧他 Debug 的姿勢準沒錯,優秀工程師們往往能夠正確地找到問題點、用精確的關鍵字找到最佳解,除了依靠經驗的累積外,更重要的是面對錯誤是否都能掌握問題原因,甚至是了解如何防範以及類似做法有哪些?身為一名 Android 工程師,今天來聊聊 Java 中的 Checked 以及 Unchecked Exception!

Checked Exception

Checked ExceptionUnchecked Exception 都是繼承自 Exception,而 Exception 則是繼承自 ThrowableChecked Exception 是在編譯階段 ( compile time ) 就會發現的錯誤,因為是已知的錯誤所以一定要Checked Exception 進行錯誤處理 ( Exception Handling ),例如用 try { } catch(e: Exception) { } 處理錯誤發生的情況,或是讓錯誤的 function 回傳 java.io.IOException。常見的 Checked Exception 像是讀取或寫入檔案時找不到檔案的 Exception ( FileNotFoundException ),或是找不到某個類別 ( ClassNotFoundException )。

Unchecked Exception

Unchecked ExceptionChecked Exception 相反,是編譯時期不會發現,到 Runtime 時才會發現的錯誤,也稱為 Runtime Exception。由於編譯器也檢查不到錯誤在哪里,因此也不會要求預先進行錯誤處理,只有到運行到該部分邏輯時才會報錯。常見的 Unchecked Exception 像是指定型別錯誤 ( ClassCastException ),空指針錯誤 ( NullPointerException,又稱 NPE )。雖然編譯器沒有要求處理 Unchecked Exception,但我們還是可以預先進行錯誤處理,例如給予預設值,或是先確認非空值再繼續操作,或是提示錯誤訊息提醒用戶,都可以預防未經處理的 Unchecked Exception 直接噴 throwable 導致 JVM 強制終止程序的崩潰。

在 Kotlin 中新增了 lateinit 可以預先定義非空值的變數,直到需要時才實作。但若在實作前就先行調用,則會拋出 UninitializedPropertyAccessException,提醒開發者該變數尚未實作,相當於在 Java 的 Setter 中加上以下的判斷:

if (value == null)
throw new UninitializedPropertyAccessException("Property has not been initialized");  

由於 lateinit 的錯誤也是 runtime 時才會發現,因此也屬於 Unchecke Exception。

有意義的錯誤

為了避免錯誤造成程序終止,開發者往往會佈下天羅地網要避免 Unchecked Exception,也有一派主張 Defensive Programming 的開發目標,無論如何都要讓程序保持持續運作,但過度的錯誤處理以避免 Exception 的發生,反而可能造成找不到錯誤進而陷入難以維護的窘境。

在應該錯誤的地方就應該報錯,對於開發者來說才是合理且可維護的程式碼。當 Exception 發生時會產生 throwable,透過throwable.printStackTrace() 可以還原錯誤發生的情況並有助於定位問題。

剛開始開發時看到 compiler 的 Logcat 上一堆紅色提示就覺得壓力山大,但害怕是因為不了解,而了解錯誤的類型是定位錯誤的第一步,後來漸漸發現原來 stacktrace 或 Log 上都藏著一堆寶貝呢!最後以主管的話和大家共勉之:)

不怕錯誤,修掉就好,怕的是 regression 的錯誤,以為修好了卻一錯再錯 (怕

#Android #Exception
透過分享開發過程中遇過的一些問題、當中的思考過程和最後的解法,期待能和更多人一起集思廣益!






Related Posts

進階 React Component Patterns 筆記(上)

進階 React Component Patterns 筆記(上)

React Native in 24 Hours

React Native in 24 Hours

人性較量Day01~圖靈測試(Turing test)

人性較量Day01~圖靈測試(Turing test)

[18] 原生功能 Natives - Array、Object、Function、RegExp、Date、Error

[18] 原生功能 Natives - Array、Object、Function、RegExp、Date、Error

[27] 強制轉型 - 寬鬆相等 ( == ) vs. 嚴格相等 ( === )

[27] 強制轉型 - 寬鬆相等 ( == ) vs. 嚴格相等 ( === )

每日心得筆記 2020-06-15(一)

每日心得筆記 2020-06-15(一)



Comments