欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

  1. 不管有沒有出現(xiàn)異常,finally塊中代碼都會(huì)執(zhí)行;
  2. 當(dāng)try和catch中有return時(shí),finally仍然會(huì)執(zhí)行;
  3. finally是在return后面的表達(dá)式運(yùn)算后執(zhí)行的(此時(shí)并沒有返回運(yùn)算后的值,而是先把要返回的值保存起來,不管finally中的代碼怎么樣,返回的值都不會(huì)改變,任然是之前保存的值),所以函數(shù)返回值是在finally執(zhí)行前確定的;
  4. finally中最好不要包含return,否則程序會(huì)提前退出,返回值不是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語句時(shí),要返回的結(jié)果已經(jīng)準(zhǔn)備好了,就在此時(shí),程序轉(zhuǎn)到finally執(zhí)行了。

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

因此,即使finally中對變量x進(jìn)行了改變,但是不會(huì)影響返回結(jié)果。

案例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

沒錯(cuò),會(huì)按照順序執(zhí)行,先執(zhí)行try內(nèi)代碼段,沒有異常的話進(jìn)入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是無論如何都會(huì)執(zhí)行的,所以try里的語句并不會(huì)直接返回。在try語句的return塊中,return返回的引用變量并不是try語句外定義的引用變量i,而是系統(tǒng)重新定義了一個(gè)局部引用 i,這個(gè)引用指向了引用 i 對應(yīng)的值,也就是 2,即使在finally語句中把引用 i 指向了值 10 ,因?yàn)閞eturn返回的引用已經(jīng)不是 i ,而是 i ,所以引用i的值和try語句中的返回值無關(guān)了。

包裝類型

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

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集合的操作生效了,這是為什么呢。我們知道基本類型在棧中存儲(chǔ),而對于非基本類型是存儲(chǔ)在堆中的,返回的是堆中的地址,因此內(nèi)容被改變了。

案例4

現(xiàn)在我們在finally里加一個(gè)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語句。但I(xiàn)DE中會(huì)對finally中加的return有黃色警告提示,這是為什么呢。

案例5

在try里加入一行會(huì)執(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

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

案例6

那如果在finally中有異常發(fā)生,會(huì)對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)

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

總結(jié)

總結(jié)以上測試:

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

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

相關(guān)文章

  • idea打不開項(xiàng)目問題的解決過程(典型案例)

    idea打不開項(xiàng)目問題的解決過程(典型案例)

    idea導(dǎo)入項(xiàng)目,起環(huán)境的時(shí)候經(jīng)常會(huì)碰到項(xiàng)目環(huán)境起不來的情況,下面這篇文章主要介紹了idea打不開項(xiàng)目問題的解決過程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java中wait()與sleep()兩者的不同深入解析

    Java中wait()與sleep()兩者的不同深入解析

    在Java多線程編程中,wait()和sleep()是控制線程執(zhí)行和等待的兩個(gè)關(guān)鍵方法,但它們在應(yīng)用場景和實(shí)現(xiàn)上有顯著差異,這篇文章主要介紹了Java中wait()與sleep()兩者的不同,需要的朋友可以參考下
    2024-11-11
  • spring?boot?Mybatis?攔截器實(shí)現(xiàn)拼接sql和修改的代碼詳解

    spring?boot?Mybatis?攔截器實(shí)現(xiàn)拼接sql和修改的代碼詳解

    這篇文章主要介紹了spring?boot?Mybatis?攔截器實(shí)現(xiàn)拼接sql和修改,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • Java異步非阻塞編程的幾種方式總結(jié)

    Java異步非阻塞編程的幾種方式總結(jié)

    這篇文章主要介紹了Java異步非阻塞編程的幾種方式總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • SpringBoot實(shí)現(xiàn)過濾器攔截器的耗時(shí)對比

    SpringBoot實(shí)現(xiàn)過濾器攔截器的耗時(shí)對比

    這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)過濾器攔截器的輸出接口耗時(shí)對比,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-06-06
  • java操作mysql實(shí)現(xiàn)增刪改查的方法

    java操作mysql實(shí)現(xiàn)增刪改查的方法

    這篇文章主要介紹了java操作mysql實(shí)現(xiàn)增刪改查的方法,結(jié)合實(shí)例形式分析了java操作mysql數(shù)據(jù)庫進(jìn)行增刪改查的具體實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-05-05
  • Java AOP知識詳細(xì)介紹

    Java AOP知識詳細(xì)介紹

    這篇文章主要介紹了Java AOP知識詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • IDEA類和方法注釋模板設(shè)置(非常詳細(xì))

    IDEA類和方法注釋模板設(shè)置(非常詳細(xì))

    這篇文章主要介紹了IDEA類和方法注釋模板設(shè)置(非常詳細(xì)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • Spring注解和同步鎖不能同步問題解決

    Spring注解和同步鎖不能同步問題解決

    這篇文章主要介紹了Spring注解和同步鎖不能同步問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • java后臺驗(yàn)證碼生成的實(shí)現(xiàn)方法

    java后臺驗(yàn)證碼生成的實(shí)現(xiàn)方法

    在我們使用進(jìn)行系統(tǒng)開發(fā)時(shí),為了提高系統(tǒng)的安全性,在登錄的時(shí)候多數(shù)人都會(huì)要求輸入驗(yàn)證,本文介紹了java后臺驗(yàn)證碼生成的實(shí)現(xiàn)方法,感興趣的一起來了解一下
    2021-05-05

最新評論