try-catch-finally的執(zhí)行順序是:1、不管有沒(méi)有出現(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、不管有沒(méi)有出現(xiàn)異常,finally塊中代碼都會(huì)執(zhí)行;
2、當(dāng)try和catch中有return時(shí),finally仍然會(huì)執(zhí)行;
3、finally是在return后面的表達(dá)式運(yùn)算后執(zhí)行的(此時(shí)并沒(méi)有返回運(yùn)算后的值,而是先把要返回的值保存起來(lái),不管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; }
沒(méi)錯(cuò),會(huì)按照順序執(zhí)行,先執(zhí)行try內(nèi)代碼段,沒(mé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換成引用類型而不是基本類型呢,來(lá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ǔ)句塊中返回的。可見(jiàn),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里的異常信息,也就是說(shuō)一旦finally里發(fā)生異常,try、catch里的異常信息即被消化掉了,也達(dá)不到異常信息處理的目的。
總結(jié)以上測(cè)試:
1、finally語(yǔ)句總會(huì)執(zhí)行
2、如果try、catch中有return語(yǔ)句,finally中沒(méi)有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常常是用來(lái)關(guān)閉流或者數(shù)據(jù)庫(kù)資源的,并不額外做其他操作。
更多相關(guān)知識(shí),請(qǐng)?jiān)L問(wèn)?PHP中文網(wǎng)??!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

The usage of return in C language is: 1. For functions whose return value type is void, you can use the return statement to end the execution of the function early; 2. For functions whose return value type is not void, the function of the return statement is to end the execution of the function. The result is returned to the caller; 3. End the execution of the function early. Inside the function, we can use the return statement to end the execution of the function early, even if the function does not return a value.

The difference between final, finally, and finalize in Java requires specific code examples. In Java programming, you often encounter the three keywords final, finally, and finalize. Although they are spelled similarly, they have different meanings and usages. This article will explain the differences between these three keywords in detail and give code examples to help readers better understand. 1. Final keyword The final keyword can be used for classes, methods and variables. Its function is to make the modified class

Source code: publicclassReturnFinallyDemo{publicstaticvoidmain(String[]args){System.out.println(case1());}publicstaticintcase1(){intx;try{x=1;returnx;}finally{x=3;}}}#Output The output of the above code can simply conclude: return is executed before finally. Let's take a look at what happens at the bytecode level. The following intercepts part of the bytecode of the case1 method, and compares the source code to annotate the meaning of each instruction in

Audio output and input require specific drivers and services to work as expected on Windows 11. These sometimes end up running into errors in the background, causing audio issues like no audio output, missing audio devices, distorted audio, etc. How to Fix Audio Service Not Responding on Windows 11 We recommend you to start with the fixes mentioned below and work your way through the list until you manage to resolve your issue. The audio service may become unresponsive for a number of reasons on Windows 11. This list will help you verify and fix most issues that prevent audio services from responding on Windows 11. Please follow the relevant sections below to help you through the process. Method 1: Restart the audio service. You may encounter

Usage of return in JavaScript requires specific code examples In JavaScript, the return statement is used to specify the value returned from a function. Not only can it be used to end the execution of a function, it can also return a value to the place where the function was called. The return statement has the following common uses: Return a value The return statement can be used to return a value to the place where the function is called. Here is a simple example: functionadd(a,b){

Vue3.2 setup syntax sugar is a compile-time syntax sugar that uses the combined API in a single file component (SFC) to solve the cumbersome setup in Vue3.0. The declared variables, functions, and content introduced by import are exposed through return, so that they can be used in Vue3.0. Problems in use 1. There is no need to return declared variables, functions and content introduced by import during use. You can use syntactic sugar //import the content introduced import{getToday}from'./utils'//variable constmsg='Hello !'//function func

JavaScript functions provide two interfaces to interact with the outside world. The parameters serve as the entrance to receive external information; the return value serves as the outlet to feed back the operation results to the outside world. The following article will take you to understand the JavaScript function return value and briefly analyze the usage of the return statement. I hope it will be helpful to you!

How to use try and catch in C requires specific code examples. In C language, there is no built-in try and catch mechanism for exception handling. However, the functionality of try and catch can be simulated by using the setjmp and longjmp functions. Below I will introduce in detail how to use these two functions for exception handling and give corresponding code examples. First, we need to understand the principles of the setjmp and longjmp functions. When the setjmp function is called, the current program will be saved.
