<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java 異常處理try、catch、finally和return執行順序

      問題背景

      finally語句一定執行嗎

      ?? 網上有很多人探討Java中異常捕獲機制 try...catch...finally 塊中的finally語句是不是一定會被執行?很多人都說不是,當然他們的回答是正確的,至少有兩種情況下finally語句是不會被執行的:

      ?? (1)try語句沒有被執行到就不會執行finally。如在try語句之前程序結束執行,那么finally語句就不會執行,這也說明了finally語句被執行的必要而非充分條件是相應的try語句一定被執行到

      ?? (2)在try塊中執行了System.exit(0)。System.exit(0)的作用是終止Java虛擬機,連JVM都停止了,所有都結束了,當然finally語句也不會被執行到。

      finally語句與return的執行順序

      ?? 還有很多人探討finally語句的執行與return的關系,讓人頗為迷惑,不知道finally語句是在try的return之前執行還是之后執行?我覺得應該是:finally語句是在try的return語句執行之后,return返回之前執行。這樣的說法有點矛盾,也許是我表述不太清楚,下面我給出自己試驗的一些結果和示例進行佐證,有什么問題歡迎大家提出來。

      ??記return后的語句為y=f(),則finally語句在f()執行之后、y返回之前執行。

      問題分析

      1. finally語句在f()執行之后、y返回之前執行

      public class FinallyTest1 {
      
          public static void main(String[] args) {
                System.out.println(test1());
          }
      
          public static String test1() {
              try {
                  System.out.println("try block");
                   // ①計算 f() 結果,記作 y,② 執行 finally,③ 返回 y
                  return test2();
              } finally {
                  System.out.println("finally block");
              }
          }
      
          public static String test2() {
              System.out.println("return statement");
              return "after return";
          }
      

      ??運行結果為:

      try block
      return statement
      finally block
      after return

      ??說明try中的f() = test2() 先執行了,得到結果y,并且待finally塊執行結束后再返回y。這里大家可能會想:如果finally里也有return語句,那么是不是就直接返回了,try中的return就不能返回了?看下面。

      2. finally塊中的return語句覆蓋try塊中的y

      public class FinallyTest2 {
         public static void main(String[] args) {
            System.out.println(test2());
         }
          public static int test2() {
              int b = 20;
              try {
                  System.out.println("try block");
                  return b += 80;
              } catch (Exception e) {
                  System.out.println("catch block");
              } finally {
                  System.out.println("finally block");
                  if (b > 25) {
                      System.out.println("b>25, b = " + b);
                  }
                  return 200;//可以被“具體值”覆蓋
              }
              // return b;
          }
      

      運行結果是:

      try block
      finally block
      b>25, b = 100
      200

      這說明finally里的return直接返回了,就不管try中是否還有返回語句,這也是不建議在finally中使用return的原因。這里還有個小細節需要注意,finally里加上return過后,try...catch...finally 外面的return b就變成不可到達語句了,也就是永遠不能被執行到,所以需要注釋掉;否則,編譯失敗。

      那么直接從finally中返回了,這也是不建議在finally中return的原因。

      這里大家可能又想:如果finally里沒有return語句,但修改了b的值,那么try中return返回的是修改后的值還是原值?看下面。

      3. finally語句塊不改變棧中的值,可改變堆中的值

      本節討論如下場景:finally中沒有return語句,但是改變了要返回的值。返回值y的類型如果是基本類型,則在finally塊里被修改也不影響y,如果是引用類型則可以。如果y是文本字符串,也不受影響。

      返回基本類型變量時是值,返回引用類型時是指向某個對象的地址;而且基本類型是被分配在棧中的,對象是被分配在堆中的,只要有引用指向這個對象,系統就不會回收此對象,所以可以在后面的finally塊中改變引用指向的對象的內容,卻無法改變try語句中return要返回的值,因為這個值已經與變量y無關了。

      測試用例1:

      public class FinallyTest3 {
      public static void main(String[] args) {
      System.out.println(test3());
      }
          public static int test3() {
              int b = 20;
              try {
                  System.out.println("try block");
                  return b += 80;
              } catch (Exception e) {
                  System.out.println("catch block");
              } finally {
                  System.out.println("finally block");
                  if (b > 25) {
                      System.out.println("b>25, b = " + b);
                  }
                  b = 150; //基本類型的返回值y,不可被修改
                  // return 3200; //可以被“具體值”覆蓋
              }
              return 2000;
          }
      
      }
      

      運行結果是:

      try block
      finally block
      b>25, b = 100
      100

      執行結果說明沒有修改y。這也驗證了finally語句塊不會影響到棧中的值,即在執行finally之前,棧中的臨時值已經確定為100了,執行finally語句將b的值變為150,對結果沒有任何影響,執行完finally后的輸出結果仍為100。

      測試用例2:

      import java.util.*;
      
      public class FinallyTest6{
      public static void main(String[] args) {
      System.out.println(getMap().get("KEY").toString());
      }
        public static Map<String, String> getMap() {
             Map<String, String> map = new HashMap<String, String>();
             map.put("KEY", "INIT");
             try {
                 map.put("KEY", "TRY");
                 return map;
             } catch (Exception e) {
                 map.put("KEY", "CATCH");
             } finally {
                 map.put("KEY", "FINALLY");// 修改y成功
                 map = null;
                 System.out.println("map是:" + map);
             }
             System.out.println("---- 走不到此處 --------");//  ①
             return map;
         }
      

      運行結果是:

      map是:null
      FINALLY
      

      為什么案例 test3()中finally里的b = 150并沒有起到作用而案例 getMap()中finally的map.put("KEY", "FINALLY")起了作用,但是map = null卻沒起作用呢?這就是Java到底是傳值還是傳址的問題了,簡單來說就是:Java中只有傳值沒有傳址,這也是為什么map = null這句不起作用。 ①處的代碼未執行說明finally外面的return 這句未執行。

      測試用例3:

          public static String testStr() {
              String b = "init";
              try {
                  System.out.println("try block");
                  return b;
              } catch (Exception e) {
                  System.out.println("catch block");
              } finally {
                  b = b + "--";
                  System.out.println("finally block, b = " + b);
              }
              return b;
          }
      

      執行結果:

      try block
      finally block, b = init--
      init
      

      說明如果y是文本字符串,在finally語句塊中改變它,也影響返回值。

      這里大家可能又要想:是不是每次返回的一定是try中的return語句呢?那么finally外的return 語句一點作用沒嗎?請看下面。

      4. try塊里的return在異常情況下不執行

      public class FinallyTest4 {
      
      public static void main(String[] args) {
      
      System.out.println(test4());
      }
      
         public static int test4() {
              int b = 20;
      
              try {
                  System.out.println("try block");
                  b = b / 0;
                  return b += 80; // ①
              } catch (Exception e) {
                  b += 15;
                  System.out.println("catch block, b = " + b);
              } finally {
                  System.out.println("finally block");
                  if (b > 25) {
                      System.out.println("b>25, b = " + b);
                  }
                  b += 50;
              }
              System.out.println("---- 走此處 --------" + b);
              return 320 + b; // ②
          }
      

      運行結果是:

      try block
      catch block, b = 35
      finally block
      b>25, b = 35
      ---- 走此處 --------85
      405

      這里因 為在return之前發生了除0異常,所以①不會被執行,而是接著執行捕獲異常的catch 語句和最終的finally語句。此時兩者對b的修改都影響了最終的返回值,從②返回的結果可以看出來。大家可能又有疑問:如果catch中有return語句呢?當然只有在異常的情況下才有可能會執行,那么是在finally之前就返回嗎?看下面。

      5. catch和try中的return執行順序相同

      public class FinallyTest5 {
      
      public static void main(String[] args) {
           System.out.println(test5());
      }
      
          public static int test5() {
              int b = 20;
              try {
                  System.out.println("try block");
                  b = b /0;
                  return b += 80;
              } catch (Exception e) {
                  System.out.println("catch block");
                  return b += 15;
              } finally {
                  System.out.println("finally block");
                  if (b > 25) {
                      System.out.println("b>25, b = " + b);
                  }
                  b += 50;
              }
              //return b;
          }
      }
      

      運行結果如下:

      try block
      catch block
      finally block
      b>25, b = 35
      35

      執行結果說明發生異常后,catch中的return語句先執行,計算完返回值y后將其保存起來,再去執行finally塊;執行完finally塊就把先去保存的y返回,finally里修改b對返回值y無影響,原因同前面的 test3() 。至此,也就推理出結論:catch中的return語句和try中的執行順序完全一樣。

      小結

      • finally塊的語句在try或catch中的return語句執行之后返回之前執行。
      • finally語句塊不改變棧中的值y,可改變堆中的值。
        y的類型如果是基本類型,其臨時存放在棧中,則在finally塊里被修改也不影響y,如果是存放在堆中的引用類型則可以。finally塊里改變文本字符串也不影響y。
      • finally里的return語句覆蓋try或catch中的return語句直接返回。

      下面看一個甲骨文的面試題:

      public class test {
          public static void main(String[] args) {
              try {
                  aMethod();
              } catch (Exception e) {
                  System.out.println("exception");// ①
              }
              System.out.println("finish");// ②
          }
      
          public static void aMethod() throws Exception {
              try {
                  throw new Exception();
              } finally {
                  System.out.println("finally"); // ③
              }
          }
      }
      

      面試題分析:首先,進入上述try代碼塊后,不管try是否拋異常,finally塊一定會執行,因此拋異常之前會執行 ③。然后,拋出的異常被調用者main方法捕獲后執行①。最后,執行②。故執行結果如下:

      finally
      exception
      finish
      

      Reference

      posted @ 2021-03-14 17:30  樓蘭胡楊  閱讀(1745)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 免费观看国产女人高潮视频| 国产在线一区二区在线视频| 长岭县| 亚洲精品中文字幕在线观| 中文无码乱人伦中文视频在线| 国产午夜精品福利视频| 激情在线网| 亚洲日韩VA无码中文字幕| 精品国产亚洲区久久露脸| 久久综合色之久久综合| 国产SM重味一区二区三区| 欧美国产激情18| 少妇精品亚洲一区二区成人| 久久精品娱乐亚洲领先| 大香伊蕉在人线国产最新2005| 成人性无码专区免费视频| 9丨精品国产高清自在线看| 高清免费毛片| 国产精品无码制服丝袜| 亚洲精品综合久久国产二区| 忘忧草在线社区www中国中文 | 欧洲性开放老太大| 久久人人爽人人爽人人片av| 国产视频不卡一区二区三区| 日韩av中文字幕有码| 成人做受视频试看60秒| 亚洲卡1卡2卡3精品| 久久精品国产久精国产果冻传媒 | 亚洲精品国产av成拍色拍个| 国产女人喷潮视频免费| 日韩中文字幕免费在线观看| 久久本道综合久久伊人| 精品亚洲男人一区二区三区| 国产精品视频中文字幕| 午夜不卡欧美AAAAAA在线观看| 丰满少妇熟乱xxxxx视频| 熟妇无码熟妇毛片| 国产啪视频免费观看视频| 日韩精品中文字幕无码一区 | 国产精品SM捆绑调教视频| 五月天免费中文字幕av|