任何Java代碼都可以?huà)伋霎惓?,如:自己編?xiě)的代碼、來(lái)自Java開(kāi)發(fā)環(huán)境包中代碼,或者Java運(yùn)行時(shí)系統(tǒng)。無(wú)論是誰(shuí),都可以通過(guò)Java的throw語(yǔ)句拋出異常。從方法中拋出的任何異常都必須使用throws子句。
1. throws拋出異常
如果一個(gè)方法可能會(huì)出現(xiàn)異常,但沒(méi)有能力處理這種異常,可以在方法聲明處用throws子句來(lái)聲明拋出異常。例如汽車(chē)在運(yùn)行時(shí)可能會(huì)出現(xiàn)故障,汽車(chē)本身沒(méi)辦法處理這個(gè)故障,那就讓開(kāi)車(chē)的人來(lái)處理。
throws語(yǔ)句用在方法定義時(shí)聲明該方法要拋出的異常類(lèi)型,如果拋出的是Exception異常類(lèi)型,則該方法被聲明為拋出所有的異常。多個(gè)異常可使用逗號(hào)分割。throws語(yǔ)句的語(yǔ)法格式為:
methodname throws Exception1,Exception2,..,ExceptionN
{
}
方法名后的throws Exception1,Exception2,…,ExceptionN 為聲明要拋出的異常列表。當(dāng)方法拋出異常列表的異常時(shí),方法將不對(duì)這些類(lèi)型及其子類(lèi)類(lèi)型的異常作處理,而拋向調(diào)用該方法的方法,由他去處理。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import java.lang.Exception; public class TestException { static void pop() throws NegativeArraySizeException { // 定義方法并拋出NegativeArraySizeException異常 int [] arr = new int [- 3 ]; // 創(chuàng)建數(shù)組 } public static void main(String[] args) { // 主方法 try { // try語(yǔ)句處理異常信息 pop(); // 調(diào)用pop()方法 } catch (NegativeArraySizeException e) { System.out.println( "pop()方法拋出的異常" ); // 輸出異常信息 } } } |
使用throws關(guān)鍵字將異常拋給調(diào)用者后,如果調(diào)用者不想處理該異常,可以繼續(xù)向上拋出,但最終要有能夠處理該異常的調(diào)用者。
pop方法沒(méi)有處理異常NegativeArraySizeException,而是由main函數(shù)來(lái)處理。
Throws拋出異常的規(guī)則:
1) 如果是不可查異常(unchecked exception),即Error、RuntimeException或它們的子類(lèi),那么可以不使用throws關(guān)鍵字來(lái)聲明要拋出的異常,編譯仍能順利通過(guò),但在運(yùn)行時(shí)會(huì)被系統(tǒng)拋出。
2)必須聲明方法可拋出的任何可查異常(checked exception)。即如果一個(gè)方法可能出現(xiàn)受可查異常,要么用try-catch語(yǔ)句捕獲,要么用throws子句聲明將它拋出,否則會(huì)導(dǎo)致編譯錯(cuò)誤
3)僅當(dāng)拋出了異常,該方法的調(diào)用者才必須處理或者重新拋出該異常。當(dāng)方法的調(diào)用者無(wú)力處理該異常的時(shí)候,應(yīng)該繼續(xù)拋出,而不是囫圇吞棗。
4)調(diào)用方法必須遵循任何可查異常的處理和聲明規(guī)則。若覆蓋一個(gè)方法,則不能聲明與覆蓋方法不同的異常。聲明的任何異常必須是被覆蓋方法所聲明異常的同類(lèi)或子類(lèi)。
例如:
判斷一個(gè)方法可能會(huì)出現(xiàn)異常的依據(jù)如下:
1)方法中有throw語(yǔ)句。例如,以上method7()方法的catch代碼塊有throw語(yǔ)句。
2)調(diào)用了其他方法,其他方法用throws子句聲明拋出某種異常。例如,method3()方法調(diào)用了method1()方法,method1()方法聲明拋出IOException,因此,在method3()方法中可能會(huì)出現(xiàn)IOException。
2. 使用throw拋出異常
throw總是出現(xiàn)在函數(shù)體中,用來(lái)拋出一個(gè)Throwable類(lèi)型的異常。程序會(huì)在throw語(yǔ)句后立即終止,它后面的語(yǔ)句執(zhí)行不到,然后在包含它的所有try塊中(可能在上層調(diào)用函數(shù)中)從里向外尋找含有與其匹配的catch子句的try塊。
我們知道,異常是異常類(lèi)的實(shí)例對(duì)象,我們可以創(chuàng)建異常類(lèi)的實(shí)例對(duì)象通過(guò)throw語(yǔ)句拋出。該語(yǔ)句的語(yǔ)法格式為:
1
|
throw new exceptionname; |
例如拋出一個(gè)IOException類(lèi)的異常對(duì)象:
1
|
throw new IOException; |
要注意的是,throw 拋出的只能夠是可拋出類(lèi)Throwable 或者其子類(lèi)的實(shí)例對(duì)象。下面的操作是錯(cuò)誤的:
1
|
throw new String(“exception”); |
這是因?yàn)镾tring 不是Throwable 類(lèi)的子類(lèi)。
如果拋出了檢查異常,則還應(yīng)該在方法頭部聲明方法可能拋出的異常類(lèi)型。該方法的調(diào)用者也必須檢查處理拋出的異常。
如果所有方法都層層上拋獲取的異常,最終JVM會(huì)進(jìn)行處理,處理也很簡(jiǎn)單,就是打印異常消息和堆棧信息。如果拋出的是Error或RuntimeException,則該方法的調(diào)用者可選擇處理該異常。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package Test; import java.lang.Exception; public class TestException { static int quotient( int x, int y) throws MyException { // 定義方法拋出異常 if (y < 0 ) { // 判斷參數(shù)是否小于0 throw new MyException( "除數(shù)不能是負(fù)數(shù)" ); // 異常信息 } return x/y; // 返回值 } public static void main(String args[]) { // 主方法 int a = 3 ; int b = 0 ; try { // try語(yǔ)句包含可能發(fā)生異常的語(yǔ)句 int result = quotient(a, b); // 調(diào)用方法quotient() } catch (MyException e) { // 處理自定義異常 System.out.println(e.getMessage()); // 輸出異常信息 } catch (ArithmeticException e) { // 處理ArithmeticException異常 System.out.println( "除數(shù)不能為0" ); // 輸出提示信息 } catch (Exception e) { // 處理其他異常 System.out.println( "程序發(fā)生了其他的異常" ); // 輸出提示信息 } } } class MyException extends Exception { // 創(chuàng)建自定義異常類(lèi) String message; // 定義String類(lèi)型變量 public MyException(String ErrorMessagr) { // 父類(lèi)方法 message = ErrorMessagr; } public String getMessage() { // 覆蓋getMessage()方法 return message; } } |