更新時間:2019-08-28 11:36:28 來源:動力節點 瀏覽2542次
今天動力節點java學院小編為大家介紹“java異常處理機制詳解”,希望對大家有幫助,下面就隨小編一起看看java異常處理機制詳解吧。
異常機制已經成為判斷一門編程語言是否成熟的標準,異常機制可以使程序中異常處理代碼和正常業務代碼分離,保證程序代碼更加優雅,并提高程序健壯性。
Java異常機制主要依賴于try、catch、finally、throw、throws五個關鍵字。
1、try:它里面放置可能引發異常的代碼。
2、catch:后面對應異常類型和一個代碼塊,用于表明該catch塊用于處理這種類型的代碼塊,可以有多個catch塊。
3、finally:主要用于回收在try塊里打開的物力資源(如數據庫連接、網絡連接和磁盤文件),異常機制總是保證finally塊總是被執行。只有finally塊,執行完成之后,才會回來執行try或者catch塊中的return或者throw語句,如果finally中使用了return或者 throw等終止方法的語句,則就不會跳回執行,直接停止。
4、throw:用于拋出一個實際的異常,可以單獨作為語句使用,拋出一個具體的異常對象。
5、throws:用在方法簽名中,用于聲明該方法可能拋出的異常。
Java的異常分為兩種,checked異常(編譯時異常)和Runtime異常(運行時異常)
1、 java認為checked異常都是可以再編譯階段被處理的異常,所以它強制程序處理所有的checked異常,而Runtime異常無須處理,java程序必須顯式處理checked異常,如果程序沒有處理,則在編譯時會發生錯誤,無法通過編譯。
2、 checked異常體現了java設計哲學:沒有完善處理的代碼根本不會被執行,體現了java的嚴謹性。
對于構造大型、健壯、可維護的應用系統而言,錯誤處理是整個應用需要考慮的重要方面。Java異常處理機制,在程序運行出現意外時,系統會生成一個Exception對象,來通知程序,從而實現將“業務功能實現代碼”和“錯誤處理代碼”分離,提供更好的可讀性。
如果執行try塊里的業務邏輯代碼時出現異常,系統會自動生成一個異常對象,該異常對象被提交給運行環境,這個過程被稱為拋出(throw)異常。Java環境收到異常對象時,會尋找合適的catch塊,如果找不到,java運行環境就會終止,java程序將退出。
不同的catch塊,視為了針對不同的異常類,提供不同的處理方法。
對于錯誤處理機制,主要有如下的兩個缺點:
1、無法窮舉所有異常情況:因為人類的知識是有限的,異常情況總比可以考慮到的情況多,總有漏網之魚。
2、錯誤處理代碼和業務實現代碼混雜嚴重影響程序的可讀性,會增加程序維護的難度。
使用try...catch捕獲異常
java提出了一種假設,如果程序可以順利完成,那么一切正常,把系統的業務實現代碼放在try塊中定義,所有的異常處理邏輯放在catch塊中進行處理。
即:
try{
//業務實現代碼
...
}
catch(Exception e){
輸入不合法
}
上面的格式中try塊和catch塊后的{...}都是不可以省略的!
執行步驟:
1、如果執行try塊中的業務邏輯代碼時出現異常,系統自動生成一個異常對象,該異常對象被提交給java運行環境,這個過程稱為拋出(throw)異常。
2、當java運行環境收到異常對象時,會尋找能處理該異常對象的catch塊,如果找到合適的cathc塊并把該異常對象交給catch塊處理,那這個過程稱為捕獲(catch)異常;如果java運行時環境找不到捕獲異常的catch塊,則運行時環境終止,jav程序也將退出。
注意1:不管程序代碼塊是否處于try塊中,甚至包括catch塊中代碼,只要執行該代碼時出現了異常,系統都會自動生成一個異常對象,如果程序沒有為這段代碼定義任何catch塊,java運行環境肯定找不到處理該異常的catch塊,程序肯定在此退出。
注意2:try塊后可以有多個catch塊,try塊后使用多個catch塊是為了針對不同異常類提供的不同的異常處理方式。當系統發生不同意外情況時,系統會生成不同的異常對象,java運行時就會根據該異常對象所屬的異常類來決定使用哪個catch塊來處理該異常。
注意3:通常情況下,如果try塊被執行一次,則try塊后只有一個catch塊會被執行,絕不可能有多個catch塊被執行,除非在循環中使用類continue開始下一次循環,下一次循環又重新運行了try塊,這才可能導致多個catch塊被執行。
注意4:進行異常捕獲時,一定要記住先捕獲小的異常,再捕獲大的異常。
Java的異常類,以及他們的繼承關系:
java把所有非正常情況分成兩種:異常(Exception)和錯誤(Error),都是繼承自Throwable父類。
Error錯誤:一般是指虛擬機相關的問題,如系統崩潰,虛擬機出錯誤等,這種錯誤無法恢復或不可能捕獲,將導致應用程序中斷,通常不處理。
Throwable():Throwable 類是 Java 語言中所有錯誤或異常的超類。只有當對象是此類(或其子類之一)的實例時,才能通過 Java 虛擬機或者 Java throw 語句拋出。類似地,只有此類或其子類之一才可以是 catch 子句中的參數類型。
1、Error(錯誤):一般是指java虛擬機相關的問題,如系統崩潰、虛擬機出錯誤、動態鏈接失敗等,這種錯誤無法恢復或不可能捕獲,將導致應用程序中斷,通常應用程序無法處理這些錯誤,因此應用程序不應該捕獲Error對象,也無須在其throws子句中聲明該方法拋出任何Error或其子類。
2、Exception:Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件。
(1)SQLException:該異常提供關于數據庫訪問錯誤或其他錯誤的信息。
(2)RuntimeException 是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。
(3)IOException:此類為異常的通用類,它是由失敗的或中斷的 I/O 操作生成的。
異常對象包含的常用方法:
1、 getMessage();返回該異常的詳細描述字符
2、printStackTrace():將該異常的跟蹤棧信息輸出到標準錯誤輸出。
3、 printStackTrace(PrintStream s):將該異常的跟蹤棧信息輸出到指定的輸出流
4、getStackTrace():返回該異常的跟蹤棧信息。
public class TestException
{
public static void main(String[] args)
{
try{
FileInputStream fis=new FileInputStream("a.txt");
}
catch(IOException ioe)
{
System.out.println(ioe.getMessage());
ioe.printStackTrace();
}
}
}
使用finally回收資源
有時候,程序在try塊里面打開了一些物力資源(比如數據庫連接,網絡連接好磁盤文件等),這些物理資源都必須顯式回收。
因為:java的垃圾回收機制不會回收任何的物理資源,垃圾回收機制只回收堆內存中對象所占用的內存。
問題1:那么在哪邊回收這些物理資源呢?
在finally塊中,因為如果try塊的某條語句引起一場,該語句后的其他語句通常不會被執行,那將導致位于該語句后的資源回收語句得不到執行;如果在catch塊里進行資源回收,但catch塊完全有可能得不到執行,這也將導致不能及時回收這些物理資源。所以我們不管try塊中的代碼是否出現異常,也不管哪個catch塊會被執行,finally塊總會被執行。
那么:java異常處理的完整語法結構如下:
try
{
//業務實現邏輯
...
}
catch(SubException e)
{
//異常處理快1
...
}
catch(SubException2 e)
{
//異常處理快2
...
}
...
finally
{
//資源回收塊
...
}
以上的異常處理語法結構中
注意點1:只有try塊石必須的,也就是說如果沒有try塊,則不可能有后面的catch塊和finally塊;
注意點2:catch塊和finally塊都是可選的,但catch塊和finally塊至少出現其中之一,也可以同時出現;
注意點3:可以有多個catch塊,捕獲父類異常的catch塊必須位于捕獲子類異常的后面;
注意點4:不能只有try塊,既沒有catch塊,也沒有finally塊;
注意點5:多個catch塊必須位于try塊之后,finally塊必須位于所有catch塊之后。
import java.io.FileInputStream;
import java.io.IOException;
public class TestException
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
FileInputStream fis = null;
try
{
fis = new FileInputStream("a.txt");
} catch (IOException ioe)
{
System.out.println(ioe.getMessage());
// return語句強制方法返回
return;
// 使用exit來退出虛擬機
// System.exit(1);
} finally
{
// 關閉磁盤文件,回收資源
if (fis != null)
{
try
{
fis.close();
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
System.out.println("程序已經執行了finally里德資源回收");
}
}
}
運行程序結果:
a.txt (系統找不到指定的文件。)
程序已經執行了finally里德資源回收
如果將catch塊中的最后兩句注釋放入程序,那么結果為:a.txt (系統找不到指定的文件。)
以上兩種情況顯示:除非在try塊或者catch塊中調用了退出虛擬機的方法(即System.exit(1);),否則不管在try塊、catch塊中執行怎樣的代碼,出現怎樣的情況,異常處理的finally塊總是會被執行的。不過,一般情況下,不要再finally塊中使用renturn或throw等導致方法終止的語句,因為一旦使用,將會導致try塊、catch塊中的return、throw語句失效。
public class TestException1
{
public static boolean test()
{
try
{
return true;
} finally
{
return false;
}
}
public static void main(String[] args)
{
boolean a = test();
System.out.println(a);
}
}
運行結果:false
以上的小程序說明:在finally塊中定義了一個renturn false語句,這將導致try塊中的return true 失去作用!
總結一下這個小問題:
當程序執行try塊,catch塊時遇到return語句或者throw語句,這兩個語句都會導致該方法立即結束,所以系統并不會立即執行這兩個語句,而是去尋找該異常處理流程中的finally塊,如果沒有finally塊,程序立即執行return語句或者throw語句,方法終止。如果有finally塊,系統立即開始執行finally塊,只有當finally塊執行完成后,系統才會再次跳回來執行try塊、catch塊里的return或throw語句,如果finally塊里也使用了return或throw等導致方法終止的語句,則finally塊已經終止了方法,不用再跳回去執行try塊、catch塊里的任何代碼了。
綜上:盡量避免在finally塊里使用return或throw等導致方法終止的語句,否則可能出現一些很奇怪的情況!
異常處理的嵌套
例如catch塊中再次包含了一個完整的異常處理流程,這種在try塊,catch塊或finally塊中包含完整的異常處理流程的情形稱為異常處理的嵌套。異常處理流程的代碼可以放在任何可執行代碼的地方,因此完整的異常處理流程既可放在try塊,也可放在catch塊,也可放在finally塊里。
嵌套的深度沒有很明確的限制,通常沒有必要寫層次太深的嵌套異常處理,會導致程序可讀性降低。
由于java異常處理機制詳解的內容太多,本文已滿,請看下文:http://m.dabaquan.cn/javazixun/1655.html
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習