Java try catch finally return 說明

本渣今天幫師兄做筆試,讀Java程序 發現答案跟我想的完全不一樣,最後一查才發現自己想的完全是錯的
,趕緊記錄一下,希望能幫到需要的人。

在實際開發中,根據 try catch 語句的執行過程,try 語句塊和 catch 語句塊有可能不被完全執行,而有些處理代碼則要求必須執行,例如文件的關閉、釋放資源等,此時就可以將這些代碼放在 finally 語句塊中。

finally 語句可以與前面介紹的 try catch 語句塊匹配使用,語法格式如下:

try{
    邏輯代碼塊
}catch(ExceptionType e){
    異常處理代碼塊
}finally{
    清理代碼塊
    文件關閉
    釋放資源
}

try catch finally 語句執行流程圖
圖一 try catch finally 語句執行流程圖

try catch finally 語句塊的執行情況可以細分爲以下 5 種情況:

  1. 如果 try 代碼塊中沒有拋出異常,則執行完 try 代碼塊之後直接執行 finally 代碼塊,然後執行 try catch finally 語句塊之後的語句。
  2. 如果 try 代碼塊中拋出異常,並被 catch 子句捕捉,那麼在拋出異常的地方終止 try 代碼塊的執行,轉而執行相匹配的 catch 代碼塊,之後執行 finally 代碼塊。如果 finally 代碼塊中沒有拋出異常,則繼續執行 try catch finally 語句塊之後的語句;如果 finally 代碼塊中拋出異常,則把該異常傳遞給該方法的調用者。
  3. 如果 try 代碼塊中拋出的異常沒有被任何 catch 子句捕捉到,那麼將直接執行 finally 代碼塊中的語句,並把該異常傳遞給該方法的調用者。
  4. 在前面的代碼中用 System.exit() 退出運行。如果代碼在 try 內部執行一條 System.exit() 語句,則應用程序將終止而不會執行 finally。
  5. 如果在執行 finally 塊之前,程序所在的線程死亡,finally 塊將不被執行。

實例1:
我知道 return a++; 是先 return 再+1的,但是如果用try/finally語句捕獲時,突然發現有三種有趣的情況:

 1. return a++;
 2. return ++a;
 3. return a+1;

分別在finally語句會有不同的輸出。

public class test {
    public static void main(String[] args) {
        System.out.println("s:"+test(1));
    }
    static int test(int a){
        try {
            //依次修改此處
            return a++;
            //return ++a;
            //return a+1;
        }finally {
            System.out.println("f:"+a);
        }
    }
}

  1. return a++;
f:2
s:1
  1. return ++a;
f:2
s:2
  1. return a+1;
f:1
s:2

我們知道finally語句是在方法結束前運行的,

原因:程序中try內部沒有異常的情況下,若有finally,且finally中沒有return。若在try中遇到return,則先跳去執行finally中的代碼,在回來執行try中return。

其實上述代碼反編譯字節碼之後會發現:

原來其實return後面的表達式,編譯器會創建臨時變量,操作完成再返回

import java.io.PrintStream;

public class Test
{

    public Test()
    {
    }

    public static void main(String args[])
    {
        System.out.println((new StringBuilder()).append("s:").append(test(1)).toString());
    }

    static int test(int a)
    {
        int i = a++;//主要改此處
        System.out.println((new StringBuilder()).append("f:").append(a).toString());
        return i;
        Exception exception;
        exception;
        System.out.println((new StringBuilder()).append("f:").append(a).toString());
        throw exception;
    }
}

實例2:

public class TryTest {
 
	public static void main(String[] args) {
		String result = get();
		System.out.println(result);
	}
	
	public static String get(){
		int value = 0;
		try {
			System.out.println("try……");
			//等式1/0 :分母爲0 的明顯錯誤          ——製造錯誤(用於拋異常)
			int result = 1 / value;
			return "111";
		} catch (Exception e) {
			System.out.println("catch……");
			return "444";
		} finally {
			System.out.println("finally……");
			return "333";
		}
		
//		return "222";
	}

結果:
在這裏插入圖片描述

經過測試:

  1. 在通過編譯器的檢查後,如果finally中有return,則以finally中的return爲準,其他的都將失效,return之前的代碼都有效。
  2. 第37行的return “222” 於catch、finally中的任何一個return互斥。也就是說,在catch、finally中其中一個地方存在return,編譯器就能檢查,已符合方法的返回要求。
  3. catch和finally中,可同時存在return,編譯能通過。但程序以finally中的return “333”爲準,不會理睬catch中的return “444”,catch中return之前的代碼仍然生效。

實例3:以下程序不會執行 try……Catch……finally之外的return,即打印的是“111”,而不打印“222”

public static void main(String[] args) {
        // 調用 測試方法
        String result = get();
        // 打印 測試方法返回的結果
        System.out.println(result);
    }

    public static String get(){
        try {
            System.out.println("try……");

            return "111";

        } catch (Exception e) {
            System.out.println("catch……");
        } finally {
            System.out.println("finally……");
        }

        return "222";
   }

結果:
在這裏插入圖片描述

參考文獻1:try、catch、finally中return的執行順序
參考文獻2:finally語句與return a++

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章