try-catch-finally的執(zhí)行順序是:1、不管有沒有出現(xiàn)異常,finally塊中的代碼都會(huì)執(zhí)行;2、當(dāng)try和catch中有return時(shí),finally仍然會(huì)執(zhí)行;3、finally是在return后面的表達(dá)式運(yùn)算后執(zhí)行的。
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中保存的返回值。
測(cè)試案例1
public class FinallyTest { public static void main(String[] args) { System.out.println(new FinallyTest().test());; } static int test() { int x = 1; try { x++; return x; } finally { ++x; } } }
結(jié)果是
2
分析:
在try語(yǔ)句中,在執(zhí)行return語(yǔ)句時(shí),要返回的結(jié)果已經(jīng)準(zhǔn)備好了,就在此時(shí),程序轉(zhuǎn)到finally執(zhí)行了。
在轉(zhuǎn)去之前,try中先把要返回的結(jié)果存放到不同于x的局部變量中去,執(zhí)行完finally之后,在從中取出返回結(jié)果,
因此,即使finally中對(duì)變量x進(jìn)行了改變,但是不會(huì)影響返回結(jié)果。
測(cè)試案例2
public static int testBasic(){ 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; }
沒錯(cuò),會(huì)按照順序執(zhí)行,先執(zhí)行try內(nèi)代碼段,沒有異常的話進(jìn)入finally,最后返回,那么輸出如下:
try block, i = 2 finally block i = 10 main test i = 10
測(cè)試案例3
public static int testBasic(){ 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); } }
輸出結(jié)果是:
try block, i = 2 finally block i = 10 main test i = 2
代碼順序執(zhí)行從try到finally,由于finally是無(wú)論如何都會(huì)執(zhí)行的,所以try里的語(yǔ)句并不會(huì)直接返回。在try語(yǔ)句的return塊中,return返回的引用變量并不是try語(yǔ)句外定義的引用變量i,而是系統(tǒng)重新定義了一個(gè)局部引用i’,這個(gè)引用指向了引用i對(duì)應(yīng)的值,也就是2,即使在finally語(yǔ)句中把引用i指向了值10,因?yàn)閞eturn返回的引用已經(jīng)不是i,而是i’,所以引用i的值和try語(yǔ)句中的返回值無(wú)關(guān)了。
但是,這只是一部分,如果把i換成引用類型而不是基本類型呢,來看看輸出結(jié)果怎樣,示例如下:
public static 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 "); } }
打印結(jié)果如下:
try block finally block main test i = [try, finally]
可以看到,finally里對(duì)list集合的操作生效了,這是為什么呢。我們知道基本類型在棧中存儲(chǔ),而對(duì)于非基本類型是存儲(chǔ)在堆中的,返回的是堆中的地址,因此內(nèi)容被改變了。
好了,現(xiàn)在我們?cè)趂inally里加一個(gè)return,看看語(yǔ)句是從哪里返回的。
public static int testBasic(){ 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; } }
輸出結(jié)果如下:
try block, i = 2 finally block i = 10 main test i = 10
可以看到,是從finally語(yǔ)句塊中返回的??梢?,JVM是忽略了try中的return語(yǔ)句。但I(xiàn)DE中會(huì)對(duì)finally中加的return有黃色警告提示,這是為什么呢,在try里加入一行會(huì)執(zhí)行異常的代碼,如下:
public static int testBasic(){ int i = 1; try{ i++; int m = i / 0 ; 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; } }
打印結(jié)果如下:
catch block i = 3 finally block i = 10 main test i = 10
可以看到,因?yàn)閒inally中有return語(yǔ)句,try、catch中的異常被消化掉了,屏蔽了異常的發(fā)生,這與初期使用try、catch的初衷是相違背的,因此編譯器也會(huì)提示警告。
那如果在finally中有異常發(fā)生,會(huì)對(duì)try、catch中的異常有什么影響呢?
public static int testBasic(){ int i = 1; try{ i++; Integer.parseInt(null); System.out.println("try block, i = "+i); return i; }catch(Exception e){ String.valueOf(null); System.out.println("catch block i = "+i); return i; }finally{ i = 10; int m = i / 0; System.out.println("finally block i = "+i); } }
這里我們?cè)趖ry、catch里強(qiáng)行加上異常語(yǔ)句,打印結(jié)果如下:
Exception in thread “main” java.lang.ArithmeticException: / by zero at tryandcatch.TryAndCatch.testBasic(TryAndCatch.java:25) at tryandcatch.TryAndCatch.main(TryAndCatch.java:45)
這個(gè)提示表示的是finally里的異常信息,也就是說一旦finally里發(fā)生異常,try、catch里的異常信息即被消化掉了,也達(dá)不到異常信息處理的目的。
總結(jié)以上測(cè)試:
1、finally語(yǔ)句總會(huì)執(zhí)行
2、如果try、catch中有return語(yǔ)句,finally中沒有return,那么在finally中修改除包裝類型和靜態(tài)變量、全局變量以外的數(shù)據(jù)都不會(huì)對(duì)try、catch中返回的變量有任何的影響(包裝類型、靜態(tài)變量會(huì)改變、全局變量)
3、盡量不要在finally中使用return語(yǔ)句,如果使用的話,會(huì)忽略try、catch中的返回語(yǔ)句,也會(huì)忽略try、catch中的異常,屏蔽了錯(cuò)誤的發(fā)生
4、finally中避免再次拋出異常,一旦finally中發(fā)生異常,代碼執(zhí)行將會(huì)拋出finally中的異常信息,try、catch中的異常將被忽略
所以在實(shí)際項(xiàng)目中,finally常常是用來關(guān)閉流或者數(shù)據(jù)庫(kù)資源的,并不額外做其他操作。
更多相關(guān)知識(shí),請(qǐng)?jiān)L問?PHP中文網(wǎng)!!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Penggunaan pulangan dalam bahasa C ialah: 1. Untuk fungsi yang jenis nilai pulangannya adalah batal, anda boleh menggunakan pernyataan pulangan untuk menamatkan pelaksanaan fungsi lebih awal 2. Untuk fungsi yang jenis nilai pulangannya tidak batal, fungsi bagi penyataan pulangan adalah untuk menamatkan pelaksanaan fungsi Hasilnya dikembalikan kepada pemanggil 3. Menamatkan pelaksanaan fungsi lebih awal, kita boleh menggunakan penyataan pulangan untuk menamatkan pelaksanaan fungsi lebih awal jika fungsi tidak mengembalikan nilai.

Perbezaan antara muktamad, akhirnya, dan memuktamadkan dalam Java memerlukan contoh kod khusus Dalam pengaturcaraan Java, anda sering menemui tiga kata kunci muktamad, akhirnya, dan memuktamadkan Walaupun ia dieja sama, ia mempunyai makna dan penggunaan yang berbeza. Artikel ini akan menerangkan perbezaan antara ketiga-tiga kata kunci ini secara terperinci dan memberikan contoh kod untuk membantu pembaca memahami dengan lebih baik. 1. Kata kunci akhir Kata kunci akhir boleh digunakan untuk kelas, kaedah dan pembolehubah. Fungsinya adalah untuk membuat kelas yang diubah suai

Output dan input audio memerlukan pemacu dan perkhidmatan tertentu untuk berfungsi seperti yang diharapkan pada Windows 11. Ini kadangkala berakhir dengan ralat di latar belakang, menyebabkan masalah audio seperti tiada output audio, peranti audio hilang, audio herot, dsb. Cara Membetulkan Perkhidmatan Audio Tidak Menjawab pada Windows 11 Kami mengesyorkan anda untuk memulakan dengan pembetulan yang dinyatakan di bawah dan menyelesaikan senarai sehingga anda berjaya menyelesaikan isu anda. Perkhidmatan audio mungkin menjadi tidak responsif atas beberapa sebab pada Windows 11. Senarai ini akan membantu anda mengesahkan dan menyelesaikan kebanyakan isu yang menghalang perkhidmatan audio daripada bertindak balas pada Windows 11. Sila ikut bahagian yang berkaitan di bawah untuk membantu anda melalui proses tersebut. Kaedah 1: Mulakan semula perkhidmatan audio yang mungkin anda hadapi

Kod sumber: publicclassReturnFinallyDemo{publicstaticvoidmain(String[]args){System.out.println(case1());}publicstaticintcase1(){intx;try{x=1;returnx;}akhirnya{x=3;}}}# Output Output kod di atas hanya boleh membuat kesimpulan: return dilaksanakan sebelum akhirnya. Mari kita lihat apa yang berlaku pada tahap bytecode. Yang berikut memintas sebahagian kod bait kaedah case1 dan membandingkan kod sumber untuk menganotasi maksud setiap arahan dalam

Penggunaan pulangan dalam JavaScript memerlukan contoh kod khusus Dalam JavaScript, pernyataan pulangan digunakan untuk menentukan nilai yang dikembalikan daripada fungsi. Ia bukan sahaja boleh digunakan untuk menamatkan pelaksanaan fungsi, ia juga boleh mengembalikan nilai ke tempat di mana fungsi itu dipanggil. Pernyataan pulangan mempunyai kegunaan biasa berikut: Mengembalikan nilai Pernyataan pulangan boleh digunakan untuk mengembalikan nilai ke tempat di mana fungsi dipanggil. Berikut ialah contoh mudah: functionadd(a,b){

Gula sintaks persediaan Vue3.2 ialah gula sintaks masa kompilasi yang menggunakan gabungan API dalam satu komponen fail (SFC) untuk menyelesaikan persediaan yang rumit dalam Vue3.0 Pembolehubah, fungsi dan kandungan yang diisytiharkan yang diperkenalkan oleh import didedahkan melalui pulangan, supaya ia boleh digunakan dalam Vue3.0 Masalah dalam penggunaan 1. Tidak perlu mengembalikan pembolehubah yang diisytiharkan, fungsi dan kandungan yang diperkenalkan semasa penggunaan Anda boleh menggunakan gula sintaksis //import kandungan yang diperkenalkan import{getToday }from'./utils'//variable constmsg='Hello !'//function function

Cara menggunakan try and catch dalam C memerlukan contoh kod khusus Dalam bahasa C, tiada mekanisme try and catch terbina dalam untuk pengendalian pengecualian. Walau bagaimanapun, kefungsian try and catch boleh disimulasikan dengan menggunakan fungsi setjmp dan longjmp. Di bawah ini saya akan memperkenalkan secara terperinci cara menggunakan kedua-dua fungsi ini untuk pengendalian pengecualian dan memberikan contoh kod yang sepadan. Pertama, kita perlu memahami prinsip fungsi setjmp dan longjmp. Apabila fungsi setjmp dipanggil, program semasa akan disimpan.

Fungsi JavaScript menyediakan dua antara muka untuk berinteraksi dengan dunia luar Parameter berfungsi sebagai pintu masuk untuk menerima maklumat luaran berfungsi sebagai saluran keluar untuk menyalurkan kembali hasil operasi kepada dunia luar. Artikel berikut akan membawa anda memahami nilai pulangan fungsi JavaScript dan menganalisis secara ringkas penggunaan penyata pulangan saya harap ia akan membantu anda!
