JAVA:異常處理
程式中的錯誤可以分為三類:
編譯錯誤,邏輯錯誤和執行時錯誤
編譯錯誤:是由於沒有遵循Java語言的語法規則而產生的,這種錯誤要在編譯階段排除,否則程式不可能執行
邏輯錯誤:編譯正常,也能執行,但結果不是人們期待的
執行時錯誤:執行過程中出現的錯誤,也有可能由邏輯錯誤引起
異常處理:主要目的是即使在程式執行時發生了錯誤,也要保證程式能正常結束,避免由於錯誤而使正在執行的程式中途停止
什麼是異常?
- 一個好的應用程式,除了具備使用者要求的功能外,還要求能預見程式執行過程中可能產生的各種異常,並把處理異常的功能包括在使用者程式中
- 異常處理機制 是JAVA語言的重要特徵之一,通過異常處理機制可防止執行期間因出現錯誤而造成不可預料的結果
- 異常是程式執行期間發生的各種意外或錯誤:
- 使用者輸入錯誤
- 記憶體不足
- 算術運算錯(數的溢位,除零操作)
- 陣列下標越界
在JAVA程式執行過程中,產生的異常通常有三種類型:
- JAVA虛擬機器由於某些內部 錯誤產生的異常,這類異常不在使用者程式控制之內,也不需要使用者處理這類異常
- 標準異常類,由JAVA系統預先定義好的。這類異常是由程式程式碼中的錯誤而產生的,如:除零操作,陣列下標越界;這些需要使用者程式處理的異常
- 根據使用者自定義的異常類
Java中所有的異常都用類表示,在JAVA中預定義了很多異常類,每個代表一種型別的執行錯誤。當程式發生異常,會生成某個異常類的物件
JAVA中標準異常類的層次結構
Java異常類都是系統類庫中的Exception類的子類,他們分佈在Java.lang .Java.io java.util java.net包中,每個異常類對應特定的執行錯誤,各個異常類採用繼承的方式進行組織。
異常舉例:
public static void main(String args[]){ int arr[]=new int[2]; for(int i=0;i<3;i++){ arr[i]=i; System.out.println(arr[i]); } }
執行結果:
0
1
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at tulun.Ex.main(Ex.java:7)
異常處理機制
JAVA對異常的處理涉及兩個方面的內容:
一是丟擲(throw)異常
二是捕捉(catch)異常
如果程式在執行過程中出現了執行錯誤,並且產生的異常與系統中預定義某個異常類相對應,系統就自動產生一個該異常類的物件,這個過程稱為丟擲異常。當異常物件丟擲時,將在程式中尋找處理這個異常的程式碼,如果找到處理程式碼,則把異常交給改程式碼段進行處理,這個過程稱為捕捉異常。如果程式中沒有給出處理異常的程式碼,則把異常交給Java執行系統預設的異常處理程式碼進行處理。預設的處理方式是:首先顯示描述異常資訊 的字串,然後終止程式的執行。
異常丟擲:
兩種方式:系統自動丟擲和利用丟擲語句丟擲
1.由系統自動丟擲異常
在程式執行過程中,如果出現了可被Java執行系統識別的錯誤,系統自動產生與該錯誤相對應的異常類的物件,即自動丟擲異常,如上面的例子
2.人為異常丟擲
- 在方法頭寫出需要丟擲的異常(利用throws語句)
- 在方法體內丟擲異常(利用throw)
Throws語句丟擲異常格式:
修飾符 返回值型別 方法名([引數表]) throws 異常類1,異常類2{
....................
}
例子:
public static void main(String args[])throws ArithmeticException,ArrayIndexOutOfBoundsException{
{
int a=4,b=0,c[]={1,2,3,4,5};
System.out.println(a/b);
System.out.println(c[a+1]);
System.out.println("end");
}
}
結果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at tulun.Ex.main(Ex.java:8)
Throw語句丟擲異常:
如果需要在方法內某個位置丟擲異常,可以使用Throw語句,通常將Throw語句與if語句配合使用
格式:
1.throw 異常類物件名
2.throw (new 異常類名())
說明:
執行throw語句時,程式終止執行後面的語句,在程式中尋找處理異常的程式碼;如果程式中沒有給出處理程式碼,則把異常交給java執行系統處理
例1:
public static void main(String args[]){
ArithmeticException e=new ArithmeticException();
int a=4,b=0;
System.out.println("Before ArithmeticException ");
if(b==0) throw e;
System.out.println(a/b);
}
Exception in thread "main" java.lang.ArithmeticException
at tulun.Ex.main(Ex.java:6)
例2:
public static void main(String args[]){
int a=5,c[]={1,2,3,4,5};
System.out.println("Before throw ArrayIndexOutOfBoundsException ");
if(a>4) throw(new ArrayIndexOutOfBoundsException());
System.out.println("After throw ArrayIndexOutOfBoundsException");
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
Before throw ArrayIndexOutOfBoundsException
例3:
public static void main(String args[]){
int a=5,b=0,c[]={1,2,3,4,5};
System.out.println("Before throw ");
if(b==0) throw (new ArithmeticException());
System.out.println(a/b);
if(a>4) throw(new ArrayIndexOutOfBoundsException());
System.out.println(c[a]);
}
Before throw
Exception in thread "main" java.lang.ArithmeticException
at tulun.Ex.main(Ex.java:8)
捕捉異常:
程式自己捕捉和處理異常,需要建立try---catch--finally語句塊
結構:
try{
//發生的異常
}
catch(異常類1 e1){
//處理異常 1;
}
...
catch(異常類n en){
//處理異常 n;
}
finally{
//不論異常是否發生,都要執行的部分;
}
說明:
(1)將可能發生異常的程式程式碼放置在try程式中。如果該塊內的程式碼出現了異常,系統將終止try塊程式碼的執行,自動跳轉到所發生的異常類對應的catch塊中,執行該塊中的程式碼。如果程式執行正常,後面的各個catch塊不起任何作用
(2)final 塊是個可選項,無論異常是否發生,finally塊的程式碼必定執行。通常把對各種異常共同處理部分放在finally塊中。如輸出統一資訊,釋放資源,
(3)一個try可對應多個catch塊,用於對多個異常類進行捕獲。但最多隻能選中一個執行
(4)異常物件與catch塊中宣告的例項的匹配原則:
異常物件是catch塊中宣告的異常類的例項;
異常物件是catch塊中宣告的異常類的某一個子類的例項;
例:
public static void main(String args[]) {
int b=0,a;
try{
System.out.println("Before throw");
a=5/b;
System.out.println("the exception is throw,the statement is't run");
}
catch(ArithmeticException e){
System.out.println("處理算數異常catch塊的捕獲");
System.out.println("捕獲的異常為"+e);
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("處理下標越界 ");
System.out.println("捕獲的異常為"+e);
}
finally{
System.out.println("try-catch-finally塊");
}
System.out.println("最後的程式碼");
}
Before throw
處理算數異常catch塊的捕獲
捕獲的異常為java.lang.ArithmeticException: / by zero
try-catch-finally塊
最後的程式碼
例2.
public static void main(String args[]) {
int a=5,b=0,c[]={1,2,3,4,5};
try{
System.out.println("Before throw");
if(a>4) throw (new ArrayIndexOutOfBoundsException());
System.out.println(c[a]);
if(b==0) throw(new ArithmeticException());
System.out.println(a/b);
System.out.println("the exception is throw,the statement is't run");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("處理下標越界 ");
System.out.println("捕獲的異常為"+e);
System.out.println(c[a]);
}
catch(ArithmeticException e){
System.out.println("處理算數異常catch塊的捕獲");
System.out.println("捕獲的異常為"+e);
System.out.println(a/b);
}
finally{
System.out.println("try-catch-finally塊");
}
System.out.println("最後的程式碼");
}
處理下標越界
捕獲的異常為java.lang.ArrayIndexOutOfBoundsException
try-catch-finally塊