Java的異常處理
Java的異常處理是通過5個關鍵字來實現的:try,catch,throw,throws,finally。JB的在線幫助中對這幾個關鍵字是這樣解釋的:
Throws: Lists the exceptions a method could throw.
Throw: Transfers control of the method to the exception handler.
Try: Opening exception-handling statement.
Catch: Captures the exception.
Finally: Runs its code before terminating the program.
try語句
try語句用大括號{}指定了一段代碼,該段代碼可能會拋棄一個或多個例外。
catch語句
catch語句的參數類似於方法的聲明,包括一個例外類型和一個例外對象。例外類型必須為Throwable類的子類,它指明了catch語句所處理的例 外類型,例外對象則由運行時系統在try所指定的代碼塊中生成並被捕獲,大括號中包含對象的處理,其中可以調用對象的方法。
catch語句可以有多個,分別處理不同類的例外。Java運行時系統從上到下分別對每個catch語句處理的例外類型進行檢測,直到找到類型相匹配的 catch語句為止。這里,類型匹配指catch所處理的例外類型與生成的例外對象的類型完全一致或者是它的父類,因此,catch語句的排列順序應該是 從特殊到一般。
也可以用一個catch語句處理多個例外類型,這時它的例外類型參數應該是這多個例外類型的父類,程序設計中要根據具體的情況來選擇catch語句的例外處理類型。
finally語句
try所限定的代碼中,當拋棄一個例外時,其后的代碼不會被執行。通過finally語句可以指定一塊代碼。無論try所指定的程序塊中拋棄或不拋棄例 外,也無論catch語句的例外類型是否與所拋棄的例外的類型一致,finally所指定的代碼都要被執行,它提供了統一的出口。通常在finally語 句中可以進行資源的清除工作。如關閉打開的文件等。
throws語句
throws總是出現在一個函數頭中,用來標明該成員函數可能拋出的各種異常。對大多數Exception子類來說,Java 編譯器會強迫你聲明在一個成員函數中拋出的異常的類型。如果異常的類型是Error或 RuntimeException, 或它們的子類,這個規則不起作用, 因為這在程序的正常部分中是不期待出現的。 如果你想明確地拋出一個RuntimeException,你必須用throws語句來聲明它的類型。
throw語句
throw總是出現在函數體中,用來拋出一個異常。程序會在throw語句后立即終止,它后面的語句執行不到,然后在包含它的所有try塊中(可能在上層調用函數中)從里向外尋找含有與其匹配的catch子句的try塊。
class myException extends Exception{
String msg;
myException(int age){
msg="age can not be positive!";
}
public String toString(){
return msg;
}
}
class Age{
public void intage(int n) throws myException{//
if(n<0||n>120){
myException e=new myException(n);
throw e; //是一個轉向語句,拋出對象實例,停止執行后面的代碼
}
if(n>=0){
System.out.print("合理的年齡!");
}
}
public static void main(String args[]) {
int a=-5;
try { //try catch 必需有
Age age = new Age();
age.intage(a);//觸發異常
System.out.print("拋出異常后的代碼") ;//這段代碼是不會被執行的,程序已經被轉向
} catch (myException ex) {
System.out.print(ex.toString());
}
finally{//無論拋不拋異常,無論catch語句的異常類型是否與所拋出的例外的類型一致,finally所指定的代碼都要被執行,它提供了統一的出口。
System.out.print("進入finally! ");
}
}
}
結果:年齡非法! 進入finally!
又如:
void fun()throws IOException,SQLException
{
...
}
這表示 fun方法可能會丟兩個異常出來,那么在調用fun的時候就會做好准備,比如可以這樣
try
{
fun();
}catch(IOException e)
{
}catch(SQLException e)
{
}
區別一:
throw 是語句拋出一個異常;throws 是方法拋出一個異常;
throw語法:throw <異常對象>
在方法聲明中,添加throws子句表示該方法將拋出異常。
throws語法:[<修飾符>]<返回值類型><方法名>([<參數列表>])[throws<異常類>]
其中:異常類可以聲明多個,用逗號分割。
區別二:
throws可以單獨使用,但throw不能;
區別三:
throw要么和try-catch-finally語句配套使用,要么與throws配套使用。但throws可以單獨使 用,然后再由處理異常的方法捕獲。
throws E1,E2,E3 只是告訴程序這個方法可能會拋出這些個異常,方法的調用者可能要處理這些異常。而這些異常E1,E2,E3可能是該函數體產生的。
而throw是明確之處這個地方要拋出這個異常。
void doA() throws Exception1, Exception3 {
try {
……
} catch(Exception1 e) {
throw e;
} catch(Exception2 e) {
System.out.println("出錯了");
}
if (a != b)
throw new Exception3("自定義異常");
}
代碼塊……中可能產生異常Exception1、Exception2和Exception3。
如果產生Exception1異常,則捕捉了之后拋出由該方法的調用者去做處理;
如果產生Exception2異常,則該方法自己做了處理(打印出了說出錯了),所以該方法就不會再向外拋出Exception2異常了,void doA() throws Exception1,,Excpetion3里面的Exception2也就不用寫了;
而Exception3異常是該方法的某段邏輯出錯,程序員自己作了處理在該段邏輯錯誤的情況下拋出異常Exception3,則調用者也需要處理。
throw語句用在方法體內,表示拋出異常,由方法體內的語句處理
throws語句用在方法聲明后面,表示再拋出異常,由調用這個方法的上一級方法中的語句來處理
throws主要是聲明這個方法會拋出這種類型的異常,使其他地方調用它時知道要捕獲這個異常。
throw是具體向外拋異常的動作,所以它是拋出一個異常實例。
throws說明你有哪個可能,傾向
throw的話,那就是你把那個傾向變成真實的了
同時:
1)throws出現在方法函數頭;而throw出現在函數體;
2)throws表示出現異常的一種可能性,並不一定會發生這些異常;throw則是拋出了異常,執行throw則一定拋出了某種異常;
3)兩者都是消極處理異常的方式(這里的消極並不是說這種方式不好),只是拋出或者可能拋出異常,但是不會由函數去處理異常,真正的處理異常由函數的上層調用處理。