-----------android培訓、java培訓、java學習型技術博客、期待與您交流!------------
異常是java程序運行的過程中出現的一些問題。將異常問題封裝為對象。(又一次體現了萬物皆對象的思想)
問題體系主要由Throwable、Error、Exception、RuntimeException(運行時異常)。如圖1所示
圖 1
Error是一些已經超出程序本身處理能力的問題,如內存溢出、虛擬機錯誤等等。這類問題一般與硬件有關,與程序本身無關,通常由系統進行處理,程序本身無法捕獲和處理。
Exception是我們在編寫程序時無法預料的異常,如調用者傳取參數異常、證書異常、實例化異常等等。為了保證java的健壯性,編寫程序時需要對這種問題進行抓取、捕獲、處理等。
Throwable體系的所以類(Throwable、其子類以及自定義異常類)及建立的對象都具備可拋性。即關鍵字Throw可以操作拋出類,throws可以操作對象。只有異常體系的類及對象具有可拋性。
異常兩種類型:RuntimeException(運行時異常)、非RuntimeException(編譯時異常)。
RuntimeException顧名思義就是這個異常在編譯期間不會發生,只有在jvm運行時才會發生。這樣做是因為發生這樣的異常時不需要編譯者進行處理的,而是希望程序停止,讓專業人員對代碼進行改正。例如(NullPointerException)空指針異常。
1 class Demo{2 public static void main(String[] args){3 Demo d = new Demo();4 int x = d.divise(4,0);5 }6 int divise(int a,int b){7 return a/b;8 }9 }
這個程序在編譯期間是檢測不出來錯誤的,因為沒有任何語法錯誤,可是在運行期間,就會報錯。這就需要我們返回去對代碼進行修改。
非RuntimeException稱作編譯時異常。該異常必須要進行處理。要么是在函數內部進行捕獲(try、catch);要么就是拋出異常對象(throw異常對象),并且在函數聲明上強調(throws 異常類)。
異常處理語句需要用到三個關鍵字:try、catch、finally。

這里需要注意的是finally中一般添加的是必須要執行的語句,及時發生異常,也會執行,比如資源關閉。只有一種情況finally中的語句才不會杯執行,那就是System.exit(0)。
在我們做項目的時候,往往遇到一些特殊的異常,或者我們不滿意java自帶的異常描述,那我們就需要自己定義異常類。牢記-------自己定義的異常類,繼承自Exception和RumtimeException。這樣自己的異常類就具有可拋性,而且可以使用異常類中的一些共性方法。如
1 class MyException extends Exception{ //或者是RuntimeException2 MyException(String str){ //字符串為自定義異常的專屬信息3 super(str);//利用Exception中的構造方法構造帶有特有信息的異常4 }5 }
將特殊的異常包裝起來,一是遵從了java的面相對象思想;二是可以將正常的運行代碼和和問題處理代碼分離,有利于閱讀。
7:異常的處理原則
1:對于異常,可以捕獲(try、catch),也可以向外拋(throws)。
2:調用到異常功能的語句,拋出(throws)幾個異常,就需要捕獲幾個異常。那這就注定了一個try,后面可以跟若干個catch語句。但有一點需要牢記的就是,捕獲異常時,異常子類往前寫,異常父類往后寫。這就像我們去補魚時,一定是網眼小的網在前面,網眼大的網在后面。如果將異常父類放在前面,子類放后面,那么一定是后面的異常不會執行。
3:當catch中捕獲到的異常無法處理時,也可以繼續向外面拋出。例如
1 try{ 2 throw new AException();3 }4 catch(AException a){5 throw e;6 }
4:如果捕獲到的異常處理不了,但與本功能無關,就可以將異常轉化為與本功能相關的功能異常,然后在拋出。
5:如果捕獲的異常可以處理,當需要將異常所產生的和本功能相關的問題提供出去,以便讓調用者知道,并處理。
1 try{ 2 throw new TransferAccountsException();3 }4 catch(TransferAccountsException a){5 轉賬失敗;//將本異常產生的,與本問題相關的問題呈現出來6 異常處理語句;//7 }
8:異常的注意事項
1:子類拋出的異常必須是父類的異常類的子類或者子集。既父類拋出一個IOException,子類只能發IOException或者及其子類。如果父類跑出三個異常類,子類也最多只能拋出三個,且這三個一定要是父類的的異常或者父類異常的子類。
2:如果父類沒有拋出異常,那么子類覆蓋之后出現異常的話,子類就只能捕獲處理,而不能往出拋。
9:異常處理的流程
1:遇到錯誤,拋出一個異常對象(如果寫程序的時候已經寫進去了,那就拋你寫的異常,如果什么都沒寫,系統就默認拋異常對象)方法立即結束,并不會返回一個值。
2:調用該方法的程序也不會繼續執行下去,而是搜索一個可以處理該異常的異常處理器,并執行其中的代碼。如下程序代碼的執行順序:first-second-third。
1 class Demo{ 2 public static void main(String[] args){ 3 Demo d = new Demo(); 4 int x = d.divise(4,0);//third:這句話也結束,同時去搜索異常處理器,并執行其中的代碼。在這里就是執行異常對象的toString(); 5 6 System.out.); 7 } 8 int divise(int a,int b){ 9 if(b==0)//first:出現錯誤10 throw new ArithmeticException("除011了");//second:拋出一個對象,同時方法結束,無返回值。11 return a/b;12 }13 }
10:總結
1:如果在方法中拋出了編譯時異常對象,則在方法聲明中就必須體現(throws);而在方法中拋出了運行時異常(RumtimeException),就不需要在方法聲明中體現。
2:對于自己的自定義異常類如何判斷其應該繼承自Exception還是RuntimeException。一般看這個異常會不會影響后續的程序運行,如果會影響,讓自定義異常類繼承自RuntimeException;如果不會影響的話,那就使自定義異常類繼承Exception。
新聞熱點
疑難解答