JAVA中return与finally的先后关系
以前一直覺(jué)得有這個(gè)問(wèn)題存在但也沒(méi)有深究,今天來(lái)徹底探討一下二者之間的關(guān)系
預(yù)備知識(shí)
首先是關(guān)于return返回的底層知識(shí)
??java方法是在棧幀中執(zhí)行,棧幀是線程私有棧的單位,執(zhí)行方法的線程會(huì)為每一個(gè)方法分配一小塊棧空間來(lái)作為該方法執(zhí)行時(shí)的內(nèi)存空間,棧幀分為三個(gè)區(qū)域:
????1. 操作數(shù)棧,用來(lái)保存正在執(zhí)行的表達(dá)式中的操作數(shù),數(shù)據(jù)結(jié)構(gòu)中學(xué)習(xí)過(guò)基于棧的多項(xiàng)式求值算法,操作數(shù)棧的作用和這個(gè)一樣
????2. 局部變量區(qū),用來(lái)保存方法中使用的變量,包括方法參數(shù),方法內(nèi)部聲明的變量,以及方法中使用到的對(duì)象的成員變量或類的成員變量(靜態(tài)變量),最后兩種變量會(huì)復(fù)制到局部變量區(qū),因此在多線程 ?????????環(huán)境下,這種變量需要根據(jù)需要聲明為volatile類型
????3. 字節(jié)碼指令區(qū),這個(gè)不用解釋了,就是方法中的代碼翻譯成的指令
關(guān)于return與finally
有了上面的預(yù)備知識(shí)我們就不難理解return和finally之間的關(guān)系了,我們要記住的就是在return [expression];
這里跟在return后面的表達(dá)式,
返回的是return指令執(zhí)行的時(shí)刻,操作數(shù)棧頂?shù)闹?#xff0c;不管expression是一個(gè)怎樣的表達(dá)式,究竟做了些什么工作,對(duì)于return指令來(lái)說(shuō)都不重要,他只負(fù)責(zé)把操作數(shù)棧頂?shù)闹捣祷亍?br /> ????而return expression是分成兩部分執(zhí)行的:
????執(zhí)行:expression;
????執(zhí)行:return指令;
????例如:return x+y;
????這句代碼先執(zhí)行x+y,再執(zhí)行return;首先執(zhí)行將x以及y從局部變量區(qū)復(fù)制到操作數(shù)棧頂?shù)闹噶?#xff0c;然后執(zhí)行加法指令,這個(gè)時(shí)候結(jié)果x+y的值會(huì)保存在操作數(shù)棧的棧頂,最后執(zhí)行return指令,返回操作數(shù)棧頂?shù)闹怠?br /> ????對(duì)于return x;先執(zhí)行x,x也是一個(gè)表達(dá)式,這個(gè)表達(dá)式只有一個(gè)操作數(shù),會(huì)執(zhí)行將變量x從局部變量區(qū)復(fù)制到操作數(shù)棧頂?shù)闹噶?#xff0c;然后執(zhí)行return,返回操作數(shù)棧頂?shù)闹怠R虼藃eturn x實(shí)際返回的是return指令執(zhí)行時(shí),x在操作數(shù)棧頂?shù)囊粋€(gè)快照或者叫副本,而不是x這個(gè)值。
而當(dāng)存在finally語(yǔ)句塊的時(shí)候,
??首先我們知道,finally語(yǔ)句是一定會(huì)執(zhí)行,但他們的執(zhí)行順序是怎么樣的呢?他們的執(zhí)行順序如下:
????1、執(zhí)行:expression,計(jì)算該表達(dá)式,結(jié)果保存在操作數(shù)棧頂;
????2、執(zhí)行:操作數(shù)棧頂值(expression的結(jié)果)復(fù)制到局部變量區(qū)作為返回值;
????3、執(zhí)行:finally語(yǔ)句塊中的代碼;
????4、執(zhí)行:將第2步復(fù)制到局部變量區(qū)的返回值又復(fù)制回操作數(shù)棧頂;
????5、執(zhí)行:return指令,返回操作數(shù)棧頂?shù)闹?#xff1b;
????我們可以看到,在第一步執(zhí)行完畢后,整個(gè)方法的返回值就已經(jīng)確定了,由于還要執(zhí)行finally代碼塊,因此程序會(huì)將返回值暫存在局部變量區(qū),騰出操作數(shù)棧用來(lái)執(zhí)行finally語(yǔ)句塊中代碼,等f(wàn)inally執(zhí)行完畢,再將暫存的返回值又復(fù)制回操作數(shù)棧頂。所以無(wú)論finally語(yǔ)句塊中執(zhí)行了什么操作,都無(wú)法影響返回值,所以試圖在finally語(yǔ)句塊中修改返回值是徒勞的。因此,finally語(yǔ)句塊設(shè)計(jì)出來(lái)的目的只是為了讓方法執(zhí)行一些重要的收尾工作,而不是用來(lái)計(jì)算返回值的。
所以在finally中更改返回值是無(wú)效的,因?yàn)樗皇歉牧瞬僮鲾?shù)棧頂端復(fù)制到局部變量區(qū)的快照,并不能真正的更改返回值,但是如果在
finally中使用return的話則是會(huì)將新的操作數(shù)棧的頂端數(shù)據(jù)返回,而不是之前復(fù)制到局部變量區(qū)用作返回內(nèi)容快照的值返回,所以這樣是可以返回的,同樣的在cathch語(yǔ)句塊里
也是這樣,只有重新出現(xiàn)了return才有可能更改返回值
原文鏈接:https://blog.csdn.net/sinat_22594643/article/details/80509266
總結(jié)
以上是生活随笔為你收集整理的JAVA中return与finally的先后关系的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java:异常处理
- 下一篇: Java:多线程之线程池