Java異常處理(異常概念、異常分類、異常的捕獲和處理)
文章目錄
一、Java異常的概念
- Java異常是Java提供的用於處理程序中錯誤的一種機制。
- 所謂錯誤是指在程序運行過程中發生的一些異常事件(如除以0溢出、數組下標越界、讀取的文件不存在等等)。
- 設計良好的程序應該在異常發生時提供處理這些錯誤的方法,使得程序不會因爲異常的發生而阻斷或產生不可預見的結果。
- Java程序執行過程中如出現異常事件,可以生成一個異常類對象,該異常對象封裝了異常事件的信息並將其提交給Java運行時系統,這個過程稱爲拋出(throw)異常。
- 當Java運行時系統接收到異常對象時,會尋找能處理這一異常的代碼並把當前異常對象交給其處理,這一過程稱爲捕獲(catch)異常。
- Java的異常指的是運行過程中出現的錯誤,觀察錯誤的名字和出錯的行號最重要,因爲Java往往在出錯的時候會告訴你出現的是什麼錯誤,是在哪一行出現的錯誤。
常見的錯誤如下:
package com.lfq.exceptionhandler;
public class TextEX {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
System.out.println(arr[4]);//數組越界異常
}
}
package com.lfq.exceptionhandler;
public class TextEX {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
System.out.println(arr[1] / 0);//除以0溢出
}
}
二、一個例子:
//語法格式
public void someMethod() throws SomeException,IOException,FileNotFoundException...{
//聲明該方法使用throws關鍵字拋出可能發生的異常
if(someCondition()){
//構造拋出異常對象,方法體中使用throw拋出異常這個異常對象
throw new SomeException(“錯誤原因”)
}
}
try{//調用該方法是試圖捕獲someMethod()方法拋出的異常
someMethod();
}catch(SomeException e){
//異常處理代碼
//e.printStackTrace();//可以打印具體出錯信息,便於調試
}catch(IOException e){
//打印信息,如除以0異常,會得到by zero的提示
e.getMessage();
}catch(FileNotFindException e){
e.printStackTrace();
}catch(....){
...
}finally{//使用finally進行文件關閉、刪除臨時文件、關閉數據庫等操作
...
}
//具體例子
void m(int i) throws ArithmeticException{ //聲明方法的同時拋出異常
if(i == 0){
throws new ArithmeticException("除數等於零");
}
}
TestEX testEX = new TestEX();//TestEX就是一個普通的測試類
try{
textEx.m(0);//這時候運行就會拋出異常,必須使用try catch或者繼續使用throws向上拋出
}catch(Exception e){
e.printStackTrace();
}
三、異常的分類
J2SDK中定義了很多異常類,這些類對應了各種各樣可能出現的異常事件。
分類詳情如下圖所示:
Error:稱爲錯誤,由Java虛擬機生成並拋出,包括動態鏈接失敗、虛擬機錯誤等,程序對其不做處理。
Exception:所有異常類的父類,其子類對應了各種各樣可能出現的異常事件,一般需要用戶顯式的聲明或者捕獲。
**Runtime Exception:**一類特殊的異常,如除數爲0、數組下標越界等,其產生比較頻繁,處理麻煩,如果顯式的聲明或捕獲將會對程序可讀性和運行效率影響很大,因此,由系統自動檢測並將它們交給缺省的異常處理程序(用戶可不必對其處理)。
四、異常的捕獲和處理
try{
//可能拋出異常的語句
}catch(SomeException e){
... ...
}catch(SomeException2){
... ...
}finally{
... ...
}
- try代碼段包含可能產生異常的代碼。
- try代碼段後跟有一個或多個catch代碼段。
- 每個catch代碼段聲明其能處理的一種特定類型的異常並提供處理的方法。
- 當異常發生時,程序會終止當前的流程,根據獲取異常的類型去執行相應的catch代碼段。
- finally段的代碼無論是否發生異常都會執行。
- 異常的捕獲和處理圖如下圖所示:
五、try語句
- try{…}語句指定了一段代碼,該段代碼就是監視代碼有可能發生異常的範圍。
- 在執行過程中,該段代碼可能會產生並拋出一種或幾種類型的異常對象,它後面的catch語句要分別對這些異常做出對應的處理。
- 如果沒有異常發生,所有的catch代碼段都被略過不執行。
六、catch語句
- 在catch語句塊中是對異常進行處理的代碼,每個try語句塊可以伴隨一個或者多個catch語句,用於處理可能發生的不同類型的異常對象。
- 在catch中聲明的異常對象(catch(SomeException))封裝了異常事件發生的信息,在catch語句塊中可以使用這個對象的一些方法獲取這些信息。
例如:
- getMessage()方法用來得到有關異常事件的信息,get zero等
- printStachTrace()方法,用來跟蹤異常事件發生時打印堆棧的信息。
七、finally語句
- finally語句爲異常處理提供一個統一的出口,使得在控制流程轉到程序的其他部分以前能夠對程序的狀態作統一管理。
- 無論try所指定的程序塊中是否拋出異常,finally所指定的代碼都會被執行。
- 通常在finally語句中進行資源的清除工作。如:關閉打開的文件,刪除臨時文件等等。
八、使用自定義異常
- 使用自定義異常一般有如下步驟:
- 通過繼承java.lang.Exception類聲明自己的異常類
- 在方法適當的位置生成自定義異常的實例,並用throw語句拋出
- 在方法的聲明部分用throws語句聲明該方法可能拋出的異常。
例如:
class MyException extends Exception{
private int id;
public MyException(String message,int id){
super(message);
this.id = id;
}
public int getId(){
return id;
}
}
//使用自定義的異常
public class Test{
public void register(int num) throws MyException{
if(num < 0){
throw new MyException("人數爲負值,不合理",3);
}
System.out.println("登記人數 " + num);
}
public void manager(){
try{
register(100);
}catch(MyException e){
System.out.println("登記失敗,出錯類型碼= " + e.getId() );
e.printStackTrace();
}
System.out.println("操作結束");
}
public static void main(String []args){
Test t = new Test();
t.manager();
}
}
九、重寫方法需要拋出與原方法所拋出異常類型一致的異常或者不拋出異常。
注意:異常類型一致指的是必須是完全一樣的,範圍大了或者小了都不行!
例如:
class A{
public void method() throws IOException(){...}
}
class B1 extend A{//報錯,和父類的異常類型不一樣
public void method() throws FileNotFoundException{...}
}
class B2 extends A{//報錯,和父類的異常類型不一樣
public void method() throws Exception{...}
}
public B4 extends A{//報錯,和父類相比存在不一樣的異常類型
public void method() throws IOException,MyException{...}
}
class B3 extends A{//正確
public void method() {...}
}
十、總結
- 一個圖(異常的分類)
- 五個關鍵字,try,catch,finally,throws,throw
- catch異常的順序,先捕獲範圍小的,再捕獲範圍大的
- 異常和重寫的關係。