正確的對待異常

前言

越是簡單,越容易忽略。編碼一切應該從簡單開始,簡單點,編碼的方式簡單點,正確點,對待異常的方式正確點。

一, JAVA異常類結構

Java異常類結構: Java異常類結構如下圖。基類爲Throwable,Error和Exception繼承Throwable,RuntimeException和IOException等繼承Exception,NullPointerException繼承RuntimeException,可以說,在Java中,除了Error之外,所有的異常類都直接或間接地繼承自Exception。
在這裏插入圖片描述
Java異常分類:

① ,非運行時/編譯時異常。在Java中,凡是繼承自Exception但不是繼承自RuntimeException的類都是非運行時異常,又稱爲編譯時異常。

② ,運行時異常。Error和所有直接或間接地繼承自RuntimeException的異常都是運行時異常,常見的有NullPointerException,IllegalArgumentException,IndexOutOfBoundsException等

Exception 含義
NullPointerException 指針
IllegalArgumentException 非法參數
IllegalStateException 非法狀態
IndexOutOfBoundsException 索引出界
UnsupportedOperationException 不支持的操作
SQLException 操作數據庫異常
ClassCastException 數據類型轉換異常
NumberFormatException 字符串轉換數字異常
ArithmeticException 除數爲0的異常
BufferOverflowException 緩衝區上溢異常
BufferUnderflowException 緩衝區下溢異常
EmptyStackException 空棧異常

二, Android異常分類

1, Java異常

在Java中出現未捕獲異常,導致程序異常終止退出。即上面說到的Java Exception中的RuntimeException。

2, ANR(Application Not Responding)

應用與用戶進行交互時,在一定時間(如主線程輸入事件中爲5秒)內沒有響應用戶的操作,則會引發ANR錯誤,並彈出一個系統提示框,讓用戶選擇繼續等待或立即關閉程序。同時會在/data/anr目錄下生成一個traces.txt文件,記錄系統產生ANR異常的堆棧和線程信息。

3, Native異常

Native異常/崩潰指在Native代碼(C/C++)中,因訪問非法地址,地址對齊等問題,或程序主動abort所產生相應的Signal導致程序異常退出。Linux中定義了很多Signal,當然並不是所有的Signal都會引發崩潰,一般會引發異常退出的Signal有SIGSEGV,SIGABRT,SIGILL,SIGBUS,SIGFPE等。Native異常具有與Java異常不同的特點:

  • 程序會直接閃退到系統桌面。
  • 出錯時不會彈出提示框提醒程序崩潰(Android5.0以下) 。

三, Android異常處理方法

1, 編譯時異常

在編譯階段被處理的異常,編譯器會強制程序處理所有的編譯時異常,也就是用try…catch顯式地捕獲並處理。Java認爲這類異常都是可以被處理/修復的,同時在Java API文檔的方法說明中,都會添加是否throw某個exception,這個exception就是編譯時異常。

2, 運行時異常

在運行時沒有相應的try…catch處理該異常對象,所以Java運行環境將會終止,程序將推出。針對這類異常處理方法:

  • 認爲加try…catch。這是一種非常low,非常不可取的方法,因爲如果所有代碼都加try…catch,那麼對代碼真正問題所在,無法處理和解決該問題。當然這樣做並不是不可取。
  • 個性化退出。我們可以在程序退出前,彈出一個個性化的對話框或者重啓應用來代替Android系統默認強制退出應用程序。實現方式可以查閱資料,這裏不做過多介紹。另外對於一些異常我們是可以做攔截操作的,比如空指針這類問題,如果出現了不讓程序崩潰,但是這些方式本人建議儘量不要去做。因爲程序中的異常本身可以看成是幫助我們查找問題,和提升程序的穩定性的,去掉或者中和掉得不償失。

四, 正確使用try…catch

  • 需要異常捕獲的地方,比如:類型轉換等。不要隨意去添加異常,分析代碼穩定性。
  • 如果有多個Exception,不要利用Exception捕獲所有潛在的異常。
  • 如果try語句塊中存在return語句,那麼首先會執行finally語句塊中的代碼,然後才返回。
  • 如果try語句塊中存在System.exit(0)語句,那麼不會執行finally語句塊的代碼,因爲System.exit(0)會終止當前運行的JVM,程序JVM終止前結束執行。
  • 當使用多個catch語句塊來捕獲異常時,需要將父類的catch語句塊放到子類型的catch塊之後,這樣才能保證後續的catch可能被執行,否則子類型的catch將永遠無法到達,Java編譯器會報編譯錯誤。
  • 不要將異常包含在for循環語句中,因爲異常處理是佔用資源的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章