大家好,今天我們來講一個筆試和面試偶爾都會問到的問題,並且在工作中不知道原理,也會造成濫用。
大家可能都知道,try 塊用來捕獲異常,catch塊是處理try塊捕獲的異常,finally 塊是用來關閉資源。一個try塊后面可以跟多個catch塊,如果后面一個catch塊也不跟,就一定要跟一個finally 塊。
結論1:當在try塊遇到return語句時,finally語句塊將在方法返回之前被執行,但是返回值不受finally塊中重新賦值的影響。
public class FinallyTest { public static void main(String[] args) throws Exception { int a = 10; int sum = throwException(a); System.out.println("執行返回結果sum:" + sum); } public static int throwException(int a) throws Exception{ int b = 20; int result = 0; try{ System.out.println("執行try語句塊"); result = a+b; return result; }catch(Exception e){ System.out.println("執行catch語句塊"); }finally{ System.out.println("執行finally語句塊"); result = 1; }
return result;
}
}
結論2:當在catch塊遇到return或者throw異常語句時,finally語句塊將在方法返回之前被執行,但是返回值不受finally塊中重新賦值的影響。
public class FinallyTest { public static void main(String[] args) throws Exception { int a = 10; int sum = throwException(a); System.out.println("執行返回結果sum:" + sum); } public static int throwException(int a) throws Exception{ int b = 20; int result = 0; try{ System.out.println("執行try語句塊"); result = b / 0; return result; }catch(Exception e){ System.out.println("執行catch語句塊"); return result; }finally{ System.out.println("執行finally語句塊"); result = 1; } } }
結論3:如果try,finally語句里均有return,忽略try的return值,而使用finally的return值
public class FinallyTest { public static void main(String[] args) throws Exception { int a = 10; int sum = throwException(a); System.out.println("執行返回結果sum:" + sum); } public static int throwException(int a) throws Exception{ int b = 20; int result = 0; try{ System.out.println("執行try語句塊"); result = a + b; return result; }catch(Exception e){ System.out.println("執行catch語句塊"); }finally{ System.out.println("執行finally語句塊"); result = 1; return result; } } }
結論4 :在finally語句塊發生了異常,finanly語句塊中異常后面的代碼不會再執行。
public class FinallyTest {
public static void main(String[] args) throws Exception {
int a = 10;
int sum = throwException(a);
System.out.println("執行返回結果sum:" + sum);
}
public static int throwException(int a) throws Exception{
int result = 30;
try{
System.out.println("執行try語句塊");
return result;
}catch(Exception e){
System.out.println("執行catch語句塊");
}finally{
int exception = b / 0;
System.out.println("執行finally語句塊");
result = 1;
}
return result;
}
}
結論5:try語句塊發生異常,並且finally語句塊也發生了異常,finally塊中的異常會掩蓋try塊中的異常。
public class FinallyTest { public static void main(String[] args) throws Exception { int a = 10; int sum = throwException(a); System.out.println("執行返回結果sum:" + sum); } public static int throwException(int a) throws Exception{ int result = 0; try{ System.out.println("執行try語句塊"); result = a / 0 ; return result; }catch(Exception e){ throw new Exception(e); }finally{ int[] arr = new int[1]; arr[2] = 3; System.out.println("執行finally語句塊"); } } }
通過上面的5個案例,我們應該對try 塊,catch塊,finally 塊中return的執行順序有了清晰的理解,下面我們在進行總結一下。
1. 當在try塊遇到return語句時,finally語句塊將在方法返回之前被執行,但是返回值不受finally塊中重新賦值的影響。
2. 當在catch塊遇到return或者throw異常語句時,finally語句塊將在方法返回之前被執行,但是返回值不受finally塊中重新賦值的影響。
3. 如果try,finally語句里均有return,忽略try的return,而使用finally的return。
4 . 在finally語句塊發生了異常,finanly語句塊異常后面的代碼不會在執行。
5:try{}語句塊發生異常,並且finally語句塊也發生了異常,finally塊中的異常會掩蓋try塊中的異常。
另外,關於1,2兩點,不受finally塊影響的原理,我做一個補充,為什么在finally塊改變try塊中的返回值,結果不受影響了?
如果try語句里有return,返回的是try語句塊中的局部變量值。 詳細執行過程如下:
①首先我們在try快中,會把返回值保存到局部變量中;
② 然后執行jsr指令跳到finally語句里執行;
③ 執行完finally語句后,返回之前保存在局部變量表里的值,所以finally塊里改變try塊中的返回值,不會生效。(但是上面第3點場景,finally自己帶return返回值除外)
感謝大家的觀看,如有錯誤之處,歡迎指出,共同學習,共同進步~
如果大家看我的文章覺得有所收獲,請將文章分享給你們的朋友,后續我會更新更多淺顯,優質的技術文章!