云漫圈 | finally到底是在return之前执行还是return之后执行?
戳藍字“CSDN云計算”關注我們哦!
——下課后——
? ?public?static?void?main(String[] args)?{
? ? ? ?query();
? ?}
? ?public?static?void?query()?{
? ? ? ?int?i =?0;
? ? ? ?try?{
? ? ? ? ? ?i ++;
? ? ? ? ? ?i = i /?0;// 拋出異常
? ? ? ? ? ?System.out.println("某一些操作");
? ? ? ?}?catch?(Exception e) {
? ? ? ? ? ?i +=?20;
? ? ? ?}?finally?{
? ? ? ? ? ?System.out.println("必需要執行的操作");
? ? ? ?}
? ?}
}
執行結果:
必需要執行的操作比如說上面所示的代碼,在try語句里面 i / 0 的話會拋出來異常,這樣的話程序就在i / 0這里由于拋出了異常,所以程序不會繼續往下去執行try包含的語句了。首先進入到catch語句里面,由于finally語句一定會執行,接下來就會執行finally中的語句,所以就得到了上面的執行結果。
比如我一些數據的關閉操作啦等,必須要執行的操作一定要放到finally語句,確保會執行。
在某些情況下,try語句壓根就沒有執行到,那么finally語句也一定就不會執行到了。
還有一種情況就是在try塊中有System.exit(0);這樣的語句,System.exit(0);是終止Java虛擬機JVM的,連JVM都停止了,所有都結束了,當然finally語句也不會被執行到。
? ?public?static?void?main(String[] args)?{
? ? ? ?int?j = query();
? ? ? ?System.out.println(j);
? ?}
? ?public?static?int?query()?{
? ? ? ?int?i =?0;
? ? ? ?try?{
? ? ? ? ? ?System.out.print("try\n");
? ? ? ? ? ?return?i +=?10;
? ? ? ?}?catch?(Exception e) {
? ? ? ? ? ?System.out.print("catch\n");
? ? ? ? ? ?i +=?20;
? ? ? ?}?finally?{
? ? ? ? ? ?System.out.print("finally-i:"+i +?"\n");
? ? ? ? ? ?i +=?10;
? ? ? ? ? ?System.out.print("finally\n");
? ? ? ? ? ?//return i;
? ? ? ?}
? ? ? ?System.out.print("finish");
? ? ? ?return?200;
? ?}
}
執行結果
tryfinally-i:10
finally
10
代碼中try語句塊中,return i+=10; 這個時候i已經是10了,這個可以從輸出的打印結果看出來,因為進入到finally語句的時候,有一個打印語句,打印結果中i就是10,就說明了return語句中的i+=10是已經執行了。
? ?public?static?void?main(String[] args)?{
? ? ? ?int?j = query();
? ? ? ?System.out.println(j);
? ?}
? ?public?static?int?query()?{
? ? ? ?int?i =?0;
? ? ? ?try?{
? ? ? ? ? ?System.out.print("try\n");
? ? ? ? ? ?return?i +=?10;
? ? ? ?}?catch?(Exception e) {
? ? ? ? ? ?System.out.print("catch\n");
? ? ? ? ? ?i +=?20;
? ? ? ?}?finally?{
? ? ? ? ? ?System.out.print("finally-i:"+i +?"\n");
? ? ? ? ? ?i +=?10;
? ? ? ? ? ?System.out.print("finally\n");
? ? ? ? ? ?return?i;
? ? ? ?}
? ?}
}
執行結果
tryfinally-i:10
finally
20
在JVM虛擬機種,有虛擬機棧,上面的代碼中每一個方法都對應了一個棧幀,方法的執行對應的棧幀入棧,方法的執行完畢對應著棧幀的出棧。
棧幀可以理解為一個方法的運行空間。它主要由兩部分構成,一部分是局部變量表,方法中定義的局部變量以及方法的參數就存放在這張表中;另一部分是操作數棧,用來存放操作數。
剛才的兩段代碼中的finally塊中,i變量是要放到局部變量表的,每次有關于i的運算,都是要把i從局部變量表取出來(可以理解為copy一個副本),比如i += 10,那么需要把i和10都放到操作數棧中進行計算,然后得到一個結果,而這個結果是需要通過retrun語句寫回到局部變量表。
第一段代碼中的finally塊中,雖然執行了i += 10,但是由于沒有return,所以局部變量表中的內容沒有變化,所以i還是10;
第二段代碼中的finally塊中,由于最后return i語句的執行,更新了局部變量中的i的值,所以最后返回的結果中i就是20了。
return返回后,就代表著方法執行結束,相應的該方法的棧幀就出棧了。而這個時候也就意味著,return返回是最后執行的,所以finally語句是在retrun返回之前執行的!
import java.util.List;
public?class?Main?{
? ?public?static?void?main(String[] args)?{
? ? ? ?List<String> cats =?new?ArrayList<>();
? ? ? ?cats ?= query(cats);
? ? ? ?System.out.println("----");
? ? ? ?for(String cat : cats)
? ? ? ? ? ?System.out.println(cat);
? ?}
? ?public?static?List<String>?query(List<String> cats)?{
? ? ? ?int?i =?0;
? ? ? ?try?{
? ? ? ? ? ?System.out.print("try\n");
? ? ? ? ? ?cats.add("xiaoMeng");
? ? ? ? ? ?return?cats;
? ? ? ?}?catch?(Exception e) {
? ? ? ? ? ?System.out.print("catch\n");
? ? ? ?}?finally?{
? ? ? ? ? ?System.out.print("finally\n");
? ? ? ? ? ?cats.add("qiaoGeLi");
? ? ? ?}
? ? ? ?System.out.println("finish");
? ? ? ?return?null;
? ?}
}
finally是在retrun語句執行后,return返回之前執行的,也就是說finally必執行(當然是建立在try執行的基礎上)?
finally中修改的基本類型沒有return是不影響返回結果的,有了retrun才會影響
finally中修改list ,map,set引用類型時,就算沒有return,也是是影響返回結果的
PS:表情包出自微信公眾號:叔婆飯 微博@叔婆飯spfan
推薦閱讀
關于云原生,這是最詳細的技術知識
用“AI”給吳秀波測面相,發現……
程序員一畢業就年薪 110 萬竟然是靠……
程序員鎖死服務器失蹤,公司解散 600 萬項目徹底黃了!
史上最全新媒體運營工具(121種)
一年省下1000億? 原來零售玩的是悶聲發大財
Spark+Alluxio性能調優十大技巧
從云計算到AI:NetApp的數據網絡轉型之道
1.微信群:
添加小編微信:color_ld,備注“進群+姓名+公司職位”即可,加入【云計算學習交流群】,和志同道合的朋友們共同打卡學習!
2.征稿:
投稿郵箱:liudan@csdn.net;微信號:color_ld。請備注投稿+姓名+公司職位。
喜歡就點擊“好看”吧! 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的云漫圈 | finally到底是在return之前执行还是return之后执行?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10怎么下免费office2013
- 下一篇: dell新版怎么设置u盘启动项 设置De