最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java try catch finally的執(zhí)行順序解讀

 更新時間:2025年05月16日 09:51:56   作者:二六八  
這篇文章主要介紹了Java try catch finally的執(zhí)行順序,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

try catch finally 執(zhí)行順序結論

  1. 不管有沒有出現(xiàn)異常,finally塊中代碼都會執(zhí)行;
  2. 當try和catch中有return時,finally仍然會執(zhí)行;
  3. finally是在return后面的表達式運算后執(zhí)行的(此時并沒有返回運算后的值,而是先把要返回的值保存起來,不管finally中的代碼怎么樣,返回的值都不會改變,任然是之前保存的值),所以函數(shù)返回值是在finally執(zhí)行前確定的;
  4. finally中最好不要包含return,否則程序會提前退出,返回值不是try或catch中保存的返回值。

案例1

public class FinallyTest {

    public static void main(String[] args) {
        System.out.print(new FinallyTest().test1());
    }

    int test1(){
        int x = 1;
        try {
            return ++x;
        }finally {
            ++x;
        }
    }
}

2

分析:在try語句中,在執(zhí)行return語句時,要返回的結果已經(jīng)準備好了,就在此時,程序轉到finally執(zhí)行了。

在轉去之前,try中先把要返回的結果存放到不同于x的局部變量中去,執(zhí)行完finally之后,在從中取出返回結果,

因此,即使finally中對變量x進行了改變,但是不會影響返回結果。

案例2

public class FinallyTest {

    public static void main(String[] args) {
        System.out.print(new FinallyTest().test2());
    }

    int test2(){
        int i = 1;
        try{
            i++;
            System.out.println("try block, i = "+i);
        }catch(Exception e){
            i++;
            System.out.println("catch block i = "+i);
        }finally{
            i = 10;
            System.out.println("finally block i = "+i);
        }
        return i;
    }
}

try block, i = 2
finally block i = 10
10

沒錯,會按照順序執(zhí)行,先執(zhí)行try內代碼段,沒有異常的話進入finally,最后返回。

案例3

public class FinallyTest {

    public static void main(String[] args) {
        System.out.print(new FinallyTest().test3());
    }

    int test3(){
        int i = 1;
        try{
            i++;
            System.out.println("try block, i = "+i);
            return i;
        }catch(Exception e){
            i ++;
            System.out.println("catch block i = "+i);
            return i;
        }finally{
            i = 10;
            System.out.println("finally block i = "+i);
        }
    }
}

try block, i = 2
finally block i = 10
2

分析:代碼順序執(zhí)行從try到finally,由于finally是無論如何都會執(zhí)行的,所以try里的語句并不會直接返回。在try語句的return塊中,return返回的引用變量并不是try語句外定義的引用變量i,而是系統(tǒng)重新定義了一個局部引用 i,這個引用指向了引用 i 對應的值,也就是 2,即使在finally語句中把引用 i 指向了值 10 ,因為return返回的引用已經(jīng)不是 i ,而是 i ,所以引用i的值和try語句中的返回值無關了。

包裝類型

但是,這只是一部分,如果把 i 換成引用類型而不是基本類型呢,來看看輸出結果怎樣,示例如下:

public class FinallyTest {
    public static void main(String[] args) {
        System.out.print(new FinallyTest().testWrap());
    }

    List<Object> testWrap(){
        List<Object> list = new ArrayList<>();
        try{
            list.add("try");
            System.out.println("try block");
            return list;
        }catch(Exception e){
            list.add("catch");
            System.out.println("catch block");
            return list;
        }finally{
            list.add("finally");
            System.out.println("finally block ");
        }
    }
}

try block
finally block
main test i = [try, finally]

可以看到,finally里對list集合的操作生效了,這是為什么呢。我們知道基本類型在棧中存儲,而對于非基本類型是存儲在堆中的,返回的是堆中的地址,因此內容被改變了。

案例4

現(xiàn)在我們在finally里加一個return,看看語句是從哪里返回的。

public class FinallyTest {

    public static void main(String[] args) {
        System.out.print(new FinallyTest().test3());
    }

    int test3(){
        int i = 1;
        try{
            i++;
            System.out.println("try block, i = "+i);
            return i;
        }catch(Exception e){
            i ++;
            System.out.println("catch block i = "+i);
            return i;
        }finally{
            i = 10;
            System.out.println("finally block i = "+i);
            return i;  //HERE
        }
    }
}

try block, i = 2
finally block i = 10
10

可以看到,是從finally語句塊中返回的??梢?,JVM是忽略了try中的return語句。但IDE中會對finally中加的return有黃色警告提示,這是為什么呢。

案例5

在try里加入一行會執(zhí)行異常的代碼,如下:

public class FinallyTest {

    public static void main(String[] args) {
        System.out.print(new FinallyTest().test3());
    }

    int test3(){
        int i = 1;
        try{
            i++;
            int m = i / 0; // HERE
            System.out.println("try block, i = "+i);
            return i;
        }catch(Exception e){
            i ++;
            System.out.println("catch block i = "+i);
            return i;
        }finally{
            i = 10;
            System.out.println("finally block i = "+i);
            return i;
        }
    }
}

catch block i = 3
finally block i = 10
10

可以看到,因為finally中有return語句,try、catch中的異常被消化掉了,屏蔽了異常的發(fā)生,這與初期使用try、catch的初衷是相違背的,因此編譯器也會提示警告。

案例6

那如果在finally中有異常發(fā)生,會對try、catch中的異常有什么影響呢?

public class FinallyTest {

    public static void main(String[] args) {
        System.out.print(new FinallyTest().test3());
    }

    int test3(){
        int i = 1;
        try{
            i++;
            System.out.println("try block, i = "+i);
            return i;
        }catch(Exception e){
            i ++;
            System.out.println("catch block i = "+i);
            return i;
        }finally{
            i = 10;
            int m = i / 0; // HERE
            System.out.println("finally block i = "+i);
            return i;
        }
    }
}

try block, i = 2
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at com.shigeqiu.demo.FinallyTest.test3(FinallyTest.java:21)
    at com.shigeqiu.demo.FinallyTest.main(FinallyTest.java:6)

這個提示表示的是finally里的異常信息,也就是說一旦finally里發(fā)生異常,try、catch里的異常信息即被消化掉了,也達不到異常信息處理的目的。

總結

總結以上測試:

  1. finally語句總會執(zhí)行
  2. 如果try、catch中有return語句,finally中沒有return,那么在finally中修改除包裝類型和靜態(tài)變量、全局變量以外的數(shù)據(jù)都不會對try、catch中返回的變量有任何的影響(包裝類型、靜態(tài)變量會改變、全局變量)
  3. 盡量不要在finally中使用return語句,如果使用的話,會忽略try、catch中的返回語句,也會忽略try、catch中的異常,屏蔽了錯誤的發(fā)生
  4. finally中避免再次拋出異常,一旦finally中發(fā)生異常,代碼執(zhí)行將會拋出finally中的異常信息,try、catch中的異常將被忽略
    所以在實際項目中,finally常常是用來關閉流或者數(shù)據(jù)庫資源的,并不額外做其他操作。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • spring boot actuator監(jiān)控超詳細教程

    spring boot actuator監(jiān)控超詳細教程

    Spring Boot Actuator就是一款可以幫助你監(jiān)控系統(tǒng)數(shù)據(jù)的框架,其可以監(jiān)控很多很多的系統(tǒng)數(shù)據(jù),接下來通過本文給大家介紹spring boot actuator監(jiān)控超詳細教程,感興趣的朋友一起看看吧
    2021-10-10
  • 海量數(shù)據(jù)去重排序bitmap(位圖法)在java中實現(xiàn)的兩種方法

    海量數(shù)據(jù)去重排序bitmap(位圖法)在java中實現(xiàn)的兩種方法

    今天小編就為大家分享一篇關于海量數(shù)據(jù)去重排序bitmap(位圖法)在java中實現(xiàn)的兩種方法,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • springboot2?使用activiti6?idea插件的過程詳解

    springboot2?使用activiti6?idea插件的過程詳解

    這篇文章主要介紹了springboot2?使用activiti6?idea插件,本文通過截圖實例代碼相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • Java實現(xiàn)的百度語音識別功能示例

    Java實現(xiàn)的百度語音識別功能示例

    這篇文章主要介紹了Java實現(xiàn)的百度語音識別功能,較為簡明扼要的分析了Java調用百度語音接口相關操作步驟,并給出了具體的語音識別用法代碼示例,需要的朋友可以參考下
    2018-08-08
  • web.xml?SpringBoot打包可執(zhí)行Jar運行SpringMVC加載流程

    web.xml?SpringBoot打包可執(zhí)行Jar運行SpringMVC加載流程

    這篇文章主要為大家介紹了web.xml?SpringBoot打包可執(zhí)行Jar運行SpringMVC加載流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • springboot中@Async默認線程池導致OOM問題

    springboot中@Async默認線程池導致OOM問題

    這篇文章主要介紹了springboot中@Async默認線程池導致OOM問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • Nacos配置文件使用經(jīng)驗及CAP原則詳解

    Nacos配置文件使用經(jīng)驗及CAP原則詳解

    這篇文章主要為大家介紹了Nacos配置文件使用經(jīng)驗及CAP規(guī)則詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-02-02
  • SpringBoot Shiro權限管理方式

    SpringBoot Shiro權限管理方式

    這篇文章主要介紹了SpringBoot Shiro權限管理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • 如何通過java實現(xiàn)highcharts導出圖片至excel

    如何通過java實現(xiàn)highcharts導出圖片至excel

    這篇文章主要介紹了如何通過java實現(xiàn)highcharts導出圖片至excel。文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,下面我們就來一起學習一下吧
    2019-06-06
  • 如何正確控制springboot中bean的加載順序小結篇

    如何正確控制springboot中bean的加載順序小結篇

    這篇文章主要介紹了如何正確控制springboot中bean的加載順序總結,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07

最新評論

南陵县| 台中市| 桑日县| 惠水县| 博爱县| 新巴尔虎右旗| 班戈县| 通化市| 金阳县| 沙湾县| 牙克石市| 汕头市| 武功县| 临漳县| 舒兰市| 无为县| 博客| 鄂尔多斯市| 东丽区| 闸北区| 曲沃县| 军事| 府谷县| 上高县| 岚皋县| 缙云县| 卢龙县| 石门县| 微山县| 平遥县| 离岛区| 江孜县| 乌海市| 邵阳市| 平湖市| 馆陶县| 连云港市| 三台县| 霍邱县| 益阳市| 东方市|