Java筆試面試總結—try、catch、finally語句中有return 的各種狀況

前言

以前在刷筆試題和麪試的時候常常會遇到或者被問到 try-catch-finally 語法塊的執行順序等問題,今天就抽空整理了一下這個知識點,而後記錄下來。java

正文

本篇文章主要是經過舉例的方式來闡述各類狀況,我這裏根據 try-catch-finally 語法塊分爲兩種大狀況討論:try-catch 語法塊和 try-catch-finally 語句塊,而後再在每種狀況裏再去具體討論。面試

1、try-catch 語句塊

咱們能夠看看下面程序:code

public static void main(String[] args) {

    System.out.println(handleException0());
  }

  /**
   * try,catch都有return
   * @return
   */
  private static String handleException0() {
    try{
      System.out.println("try開始");
      String s = null;
      int length = s.charAt(0);
      System.out.println("try結束");
      return "try塊的返回值";
    }catch (Exception e){
      System.out.println("捕獲到了異常");
      return "catch的返回值";
    }
  }

執行結果io

try開始
捕獲到了異常
catch的返回值語法

分析:程序首先執行 try 塊裏面的代碼,try 塊裏面發現有異常,try 塊後面的代碼不會執行(天然也不會return),而後進入匹配異常的那個 catch 塊,而後進入 catch 塊裏面將代碼執行完畢,當執行到 catch 裏面的return 語句的時候,程序停止,而後將此 return 的最終結果返回回去。程序

2、try-catch-finally 語句塊

這種語法塊我分爲了 4 種狀況討論,下面進行一一列舉。方法

一、第一種狀況,try 塊裏面有 return 的狀況,而且捕獲到異常im

例1:總結

public static void main(String[] args) {
  String result = handleException1();
  System.out.println(result);
}
private static String handleException1() {
  try{
    System.out.println("try開始");
    String str = null;
    int length = str.length();
    System.out.println("try結束");
  }catch (Exception e){
    System.out.println("捕獲到了異常");
  }finally {
    System.out.println("finally塊執行完畢了");
  }
  return "最終的結果";
}

例1執行的結果以下筆試

try開始
捕獲到了異常
finally塊執行完畢了
最終的結果

例2:

public static void main(String[] args) {
  String result = handleException2();
  System.out.println(result);
}
private static String handleException2() {
  try{
    System.out.println("try開始");
    String str = null;
    int length = str.length();
    System.out.println("try結束");
    return "try塊的返回值";
  }catch (Exception e){
    System.out.println("捕獲到了異常");
  }finally {
    System.out.println("finally塊執行完畢了");
  }
  return "最終的結果";
}

例2的執行結果以下

try開始
捕獲到了異常
finally塊執行完畢了
最終的結果

分析:首先 例1 和 例2 的結果是很顯然的,當遇到異常的時候,直接進入匹配到相對應的 catch 塊,而後繼續執行 finallly 語句塊,最後將 return 結果返回回去。

第二種狀況:try塊裏面有return的狀況,可是不會捕獲到異常

例3:

思考:下面代碼try語句塊中有return語句,那麼是否執行完try語句塊就直接return退出方法了呢?

public static void main(String[] args) {
  String result = handleException3();
  System.out.println(result);
}
private static String handleException3() {
  try{
  	System.out.println("");
    return "try塊的返回值";
  }catch (Exception e){
    System.out.println("捕獲到了異常");
  }finally {
    System.out.println("finally塊執行完畢了");
  }
  return "最終的結果";
}

例3的執行結果以下

finally塊執行完畢了
try塊的返回值

分析:例3的結果其實咱們能夠經過打斷點的方式去看看程序的具體執行流程,經過打斷點咱們能夠發現,代碼先執行 try塊 裏的代碼,當執行到 return 語句的時候,handleException3方法並無馬上結束,而是繼續執行finally塊裏的代碼,finally塊裏的代碼執行完後,緊接着回到 try 塊的 return 語句,再把最終結果返回回去, handleException 方法執行完畢。

第三種狀況:try塊和finally裏面都有return的狀況

例4:

public static void main(String[] args) {
    System.out.println(handleException4());
  }

  /**
   * 狀況3:try和finally中均有return
   * @return
   */
  private static String handleException4() {
    try{
      System.out.println("");
      return "try塊的返回值";
    }catch (Exception e){
      System.out.println("捕獲到了異常");
    }finally {
      System.out.println("finally塊執行完畢了");
      return "finally的返回值";
    }
  //  return "最終的結果";//不能再有返回值
  }

例4的執行結果

finally塊執行完畢了
finally的返回值

分析:須要注意的是,當 try 塊和 finally 裏面都有 return 的時候,在 try/catch/finally 語法塊以外不容許再有return 關鍵字。咱們仍是經過在程序中打斷點的方式來看看代碼的具體執行流程。代碼首先執行 try 塊 裏的代碼,當執行到 return 語句的時候,handleException4 方法並無馬上結束,而是繼續執行 finally 塊裏的代碼,當發現 finally 塊裏有 return 的時候,直接將 finally 裏的返回值(也就是最終結果)返回回去, handleException4 方法執行完畢。

第四種狀況:try塊,catch塊,finally塊都有return

例5:

public static void main(String[] args) {
    System.out.println(handleException5());
  }

  /**
   * 狀況4:try,catch,finally都有return
   * @return
   */
  private static String handleException5() {
    try{
      System.out.println("try開始");
      int[] array = {1, 2, 3};
      int i = array[10];
      System.out.println("try結束");
      return "try塊的返回值";
    }catch (Exception e){
      e.printStackTrace();//這行代碼其實就是打印輸出異常的具體信息
      System.out.println("捕獲到了異常");
      return "catch的返回值";
    }finally {
      System.out.println("finally塊執行完畢了");
      return "finally的返回值";
    }
//    return "最終的結果";
  }

例5的執行結果

try開始
捕獲到了異常
finally塊執行完畢了
finally的返回值
java.lang.ArrayIndexOutOfBoundsException: 10
at com.example.javabasic.javabasic.ExceptionAndError.TryCatchFinally.handleException5(TryCatchFinally.java:25)
at com.example.javabasic.javabasic.ExceptionAndError.TryCatchFinally.main(TryCatchFinally.java:14)

分析:程序首先執行try塊裏面的代碼,try塊裏面發現有異常,try塊後面的代碼不會執行(天然也不會return),而後進入匹配異常的那個catch塊,而後進入catch塊裏面將代碼執行完畢,當執行到catch裏面的return語句的時候,程序不會立刻終止,而是繼續執行finally塊的代碼,最後執行finally裏面的return,而後將此return的最終結果返回回去。

總結

其實,咱們經過以上例子咱們能夠發現,無論return關鍵字在哪,finally必定會執行完畢。理論上來講try、catch、finally塊中都容許書寫return關鍵字,可是執行優先級較低的塊中的return關鍵字定義的返回值將覆蓋執行優先級較高的塊中return關鍵字定義的返回值。也就是說finally塊中定義的返回值將會覆蓋catch塊、try塊中定義的返回值;catch塊中定義的返回值將會覆蓋try塊中定義的返回值。
再換句話說若是在finally塊中經過return關鍵字定義了返回值,那麼以前全部經過return關鍵字定義的返回值都將失效——由於finally塊中的代碼必定是會執行的。


公衆號:良許Linux

有收穫?但願老鐵們來個三連擊,給更多的人看到這篇文章

相關文章
相關標籤/搜索