JAVA的異常處理機制(一)——try...catch...finally

Alexwym發表於2018-07-27

在程式語言中,異常定義了程式中遇到的非致命的錯誤,比如,程式要開啟一個不存的檔案、網路連線中斷、除零操作、運算元越界、裝載一個不存在的類等情況。這些異常錯誤往往會導致程式中斷,無法正常執行。異常處理機制可以防止程式在出現異常時直接崩潰。它可以讓程式繼續執行,並且處理相應的錯誤(比如:列印出錯誤資訊等)。今天我們就來看一下JAVA的異常處理機制。
一、基本格式

        try {   
            //可能產生異常的程式碼部分
            //捕獲異常
        } catch (Exception e) {
            //對獲取的異常資訊進行處理
        }finally{
            //異常部分以外的程式碼
        }

二、處理流程

A.沒有出現異常時。只有catch中的程式碼不會被執行,其他部分的程式碼都會被執行。

測試程式碼:

package abnormalTest;
import java.io.IOException;

//定義一個測試類,檢查JAVA中的異常處理機制
public class Test {
	int age;
	public void Abnormal(){
        try {  
            System.out.println("執行try內部異常發生前程式碼塊");
        	int i=1;
        	int x=5/i;
        	System.out.println("執行try內部異常發生後程式碼塊");
        } catch (Exception e) {
            System.out.println("執行catch內部程式碼塊");
        }finally{
        	System.out.println("執行finally內部程式碼塊");
        }
        System.out.println("執行其他的程式碼塊");
	}
	//主函式入口
	public static void main(String[] args) {
		Test t=new Test();
		t.Abnormal();
	}
	
}

測試結果

B.try中程式碼出現異常時。catch部分程式碼會被執行,進行異常的處理。而try中發生異常之後的程式碼都不會被執行。

程式碼部分把i的值改成0以後重新執行,結果如下:

三、小結:

(1)當發生異常的時候,在try程式碼塊中捕捉異常,異常程式碼發生行之後的程式碼不再執行。

(2)只有當try程式碼塊發生異常的時候,才會執行到catch程式碼塊。

(3)不管try中是否發生異常,finally程式碼塊和try…catch...finally以外的程式碼塊都會執行(當有return關鍵字的時候,這兩個程式碼塊的執行情況還有所不同,後面會講到)。

不過當程式碼中出現System.exit(0)時需要格外小心,以下兩種情況都會導致finally和try…catch...finally以外的程式碼塊無法執行:

A.try中不發生異常時,try塊中有System.exit(0);

B.try中發生異常時,catch中有System.exit(0);

補充:System.exit(0)是退出虛擬機器的語句,可以視為強制終止程式的指令。

四、附上一道面試題

求下面函式的執行結果

	//測試return方法
	public int TestReturn() {
        try {   
            return 1;
        } catch (Exception e) {
            return 2; 
        }finally{
            return 3 ;
        }
	}

執行結果:

分析:try中沒有異常,因此會先執行return 1,不會執行catch部分的程式碼return2;然後繼續執行finally部分的程式碼return 3。最後程式返回3。有人可能會不理解,明明return就是返回了,為何還會繼續執行catch和finally部分的程式碼塊。這裡我們可以粗淺地理解為try...catch...fianlly本身設定的一種處理機制。不管有沒有異常,除非程式被強制終止,否則finally是一定要進去的。因此最後的返回值以finally裡面的為準。而如果在try、catch或者finally中執行了return語句,try...catch...finally以外的程式碼塊則不會再被執行。

從Java虛擬機器的角度來看:return指令分為兩條位元組碼指令laod和ireturn,其中ireturn語句必須在整個方法中需要執行的程式碼都執行完了他才能執行。首先執行try部分的程式碼return 1中的iload部分,先把1這個數放到運算元棧頂。然後進入finally部分,執行return 3,同樣地,把3放到運算元棧頂,覆蓋原來的1。此時JVM發現TestReturn方法中所有需要執行的程式碼塊都已經執行完畢了,於是就執行ireturn。最終返回3。

測試程式碼如下:

Unreachable code的報錯資訊說明31行是一段永遠不會執行到的程式碼.因為不管程式有沒有出現異常,都會先執行到return 語句,退出TestReturn 方法。因此如果我們有一部分程式碼需要在異常處理完之後繼續執行,最後把它放到finally裡面。

 

 

 

相關文章