Java 中的異常有很多,這種異常機制,可以幫助處理程序中未知的錯誤。關於異常的處理有try catch 程序塊、throw 、throws。
以下分別對這三種進行介紹。
一、try...catch
try-catch用來捕獲代碼段的異常並做出處理
try-catch代碼塊分兩塊,第一塊是try{} ,第二塊是catch(exception的引用){}。
try-catch一般放在循環放外。
try-catch,try即嘗試,嘗試能不能正常的走完整個作用域,如果不能則拋出一個異常。所以在try塊裏經常放上可能會拋出異常的程序段。而catch就是處理try裏拋出來的異常,其中catch的參數列表接收的是一個異常的引用,是throw拋出來的異常的引用。
try-catch可以嵌套使用,以下是一個try-catch嵌套使用的例子:
public static void main(String[] args) {
try {
System.out.println("**********************外層try**********************");
errorMethod();
} catch (Exception e) {
System.out.println("**********************外層catch" + e + "**********************");
} finally {
System.out.println("**********************外層finally**********************");
}
}
private static void errorMethod() {
try {
System.out.println("**********************內層try**********************");
int i = 0;
int a = 100 / i;
} catch (Exception e) {
System.out.println("**********************內層catch" + e + "**********************");
} finally {
System.out.println("**********************內層finally**********************");
}
}
內層函數體用零作被除數,報ArithmeticException
若是註釋掉內層catch,其他一樣:
private static void errorMethod() {
try {
System.out.println("**********************內層try**********************");
int i = 0;
int a = 100 / i;
} /*catch (Exception e) {
System.out.println("**********************內層catch" + e + "**********************");
}*/ finally {
System.out.println("**********************內層finally**********************");
}
}
運行結果是:
總結一個報錯後的執行順序:
try {
//A 報錯地方
try {
//B
} catch (Exception e) {
//C
} finally {
//D
}
//E
} catch (Exception e) {
//F
} finally {
//G
}
執行順序:
- 內層A,E處拋出異常:由外層catch塊捕獲,並執行外層finally ;
- 內層B處拋出異常,且有一合適內層catch捕獲在:執行內層finally,後執行E處 ;
- 內層B處拋出異常,但內層catch塊沒有合適處理程序:執行內層finally,搜索外層catch,找合適的,執行外層finally,此時不會執行E ;
- 內層C處拋出異常在:退出內層catch塊,執行內層finally,搜索外層catch,找到合適,執行外層finally ;
- 內層D處拋出異常在:退出內層finally塊,搜索外層catch,找到合適,執行外層finally
總結:
1.try-catch 嵌套內層catch 可以捕獲異常時,外層catch不會執行,但finally (多用於IO關閉)都會執行。
2.try-catch一般用在最上層的程序裏,可以配合throws和throw再將異常拋給用戶,這種情況會使上層代碼中斷。也可以不選擇拋出,這種上層代碼會繼續運行。
3.被調用的方法如果有異常的可能可以通過throws拋給上層處理,不加try catch的情況如下會自動往上拋,加了try catch需要如上通過throw拋給上層程序。
二、throw
throw 即拋出一個異常,並獲取這個異常的引用,這個異常會被拋到外部的環境,由外部環境進行處理。
throw 一般會用於程序出現某種邏輯時程序員主動拋出某種特定類型的異常。
class A{
public void func() throws Exception{
throw new Exception();
}
}
這裏拋出了一個Exception,Exception是throwable的子類,是所有異常的基類。與此同時,throwable還有另一個子類,也就是Error。這裏會把Exception這個引用拋到外部環境中去處理。
throw跟try...catch...finally的對比:
try catch是直接處理,處理完成之後程序繼續往下執行,throw則是將異常拋給它的上一級處理,程序便不往下執行了。
public class ZeroTest {
public static void main(String[] args) {
try{
int i = 100/ 0;
System.out.print(i);
}catch(Exception e){
System.out.print(1);
throw new RuntimeException();
}finally{
System.out.print(2);
}
System.out.print(3);
}
}
上述代碼中的catch語句塊裏面,打印完1之後,又拋出了一個RuntimeException,程序並沒有處理它,而是直接拋出,
因此執行完finally語句塊之後,程序終止了。
首先執行try,遇到算術異常,拋出,執行catch,打印1,然後拋出RuntimeException,緩存異常,執行finally,打印2,然後拋出RuntimeException。
如果catch中沒有拋出RuntimeException,則執行結果爲123。
三、throws
throws並不是拋出一個實際的Exception而是一個異常聲明,它聲明這個方法可能會拋出一個異常,注意是可能,所以在沒有異常的情況下也是可以用throws的,而throws本身的作用也是用來提高程序的健壯性,反過來,如果這個方法的的確有一個異常,那麼編譯器會強制讓加上throws異常聲明。
通常throws是寫在參數列表的後面,表明這個方法有可能會拋出一個異常。
class A{
public void g() throws Exception{
}
}
四、try-catch、throw、throws之間的區別與聯繫
區別一:
throw 是語句拋出一個異常;throws 是方法拋出一個異常;
throw語法:throw <異常對象>
throws語法:[<修飾符>]<返回值類型><方法名>([<參數列表>])[throws<異常類>]
在方法聲明中,添加throws子句表示該方法將拋出異常。如果一個方法會有異常,但你並不想處理這個異常,就在方法名後面用throws,這樣這個異常就會拋出,誰調用了這個方法誰就要處理這個異常,或者繼續拋出。其中:異常類可以聲明多個,並用逗號分割。
區別二:
throw可以與try-catch-finally語句塊一起使用,也可以與throws一起使用。
throws一般單獨使用,然後再由處理異常的方法捕獲。
聯繫一:
try .... catch 就是用catch 捕獲 try 中某一個操作可能會出現的異常並處理。
throw 不處理異常,而直接拋出異常。throw new Exception()是拋出一個Exception,由其他的method來處理這個Exception。
所以:try....catch是爲捕獲Exception用的,而throw是拋出Exception讓別人去捕獲。
如果一個方法中用了throws,那麼這個方法會向上拋出一個異常,那麼在調用這個方法的時候必須把這個調用放在try...catch塊裏處理這個異常。
異常的處理方法有兩種:
1、聲明異常,即在方法名後面加上throws ExceptionName,..., 方法本身只是拋出異常,由函數調用者來捕獲異常。若產生異常,異常會順着調用棧一直找到與之匹配的處理方法,若到達調用棧底仍未找到,就輸出異常並終止程序。
2、捕獲異常。通過try catch方法,catch子句中放置處理異常的語句。
聯繫二:
對於可能有異常拋出的程序塊,用try{}包住,然後用catch來抓住這個異常,在catch中對異常做處理, 在try中如果有異常的話,程序會轉到catch而不會中斷。
try和catch只能獲取程序運行時引發的異常,而throw語句可以引發明確的異常,程序到了throw語句這後就立即停止,不會執行後面的程序。
本文部分段落摘自以下文章:
https://blog.csdn.net/qq_30715329/article/details/85463461