您好,登錄后才能下訂單哦!
本篇文章為大家展示了深入淺析java項目中return語句的執(zhí)行順序,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
原題
try {} 里有一個return語句,那么緊跟在這個try后的finally {}里的代碼會不會被執(zhí)行?什么時候被執(zhí)行?在return前還是后?
栗子代碼
public static void main(String[] args) { int result = test(); System.out.println(result); } public static int test() { int t = 0; try { return t; } finally { ++t; } }
分析一下
test()
方法內(nèi),在try中return了t,那么在main方法中test()
函數(shù)的返回值應該是t=0,即控制臺輸出0
但是因為有finally的存在,而finally中對t進行了自增運算,并且finally會在try中的return語句之前執(zhí)行,所以正確的情況是控制臺輸出1
所以你最終確定的答案是:控制臺輸出1
然而事實并非如此,將程序跑起來之后,得到的結(jié)果是:
輸出0
將栗子跑起來親眼看一下吧~
得到這個結(jié)果你也許要爆炸了,啥?java規(guī)范說的都是錯的?!
不用急,到我給sun洗地的時間了
洗地時間
在洗地之前,你很有必要先理解java中的值傳遞,如果你已經(jīng)了解該內(nèi)容可略過下面這一個小節(jié)點
java中的值傳遞
由于這只是本文內(nèi)容引申出去的知識點,不過多贅述,隨便嘮兩句,能借此明白則好,不明白希望借助搜索引擎明白一下!
在java的方法調(diào)用中,時常需要傳遞參數(shù),那么傳遞的參數(shù)是將之前的變量直接傳遞給方法內(nèi)了嗎?
顯然不是的,調(diào)用方法傳遞參數(shù)的時候,傳遞的只是原變量的一個副本(復制體),換句話說就是,將變量的值傳遞給了方法體,而并沒有真正的將變量傳遞進去。
看個栗子:
public static void main(String[] args) { int t = 0; test(t); System.out.println(t); } public static int test(int a) { a = 111; }
正確輸出是0,因為test()
方法內(nèi)拿到的a,只是t的一個副本(復制體)而并不直接是t,test()
內(nèi)改變了a的值,并不影響t的值
以上是對于基本數(shù)據(jù)類型,如果對于對象呢?
如果參數(shù)是對象,那么傳遞的是對象的引用的副本(復制體),這也就是為什么在方法體內(nèi)對對象進行修改,會真正的改變對象。因為方法體外的引用和方法體內(nèi)的引用指向的是堆內(nèi)存中的同一個對象,傳遞的是對象的引用
如果這里還不能理解值傳遞,建議先理解一下這一個概念再繼續(xù)往下看
真的開始分析了
為了你看著方便,栗子代碼再來一份:(我真的不是為了湊字數(shù))
public static void main(String[] args) { int result = test(); System.out.println(result); } public static int test() { int t = 0; try { return t; } finally { ++t; } }
上圖或許直觀一點?
那么如果,這個t是一個對象呢?按照前面說的值傳遞的問題,如果t是一個對象,在finally中對t進行修改,那么最終返回出去的t所顯示出來的數(shù)據(jù),應該是經(jīng)過修改的。
寫一個Person類來檢驗一下吧
public class Test { public static void main(String[] args) { Person result = test(); System.out.println(result.age); } public static Person test() { Person t = new Person(); t.age = 0; try { return t; } finally { t.age++; } } } class Person { int age; }
這段代碼輸出的是1,因為Person是一個類,t是一個對象的引用,對象實例保存在堆內(nèi)存中,t的副本tt也是一個對象的引用,t和tt都指向堆內(nèi)存中的對象實例,那么不論修改誰,實際上對象實例都被修改了!
看完我這一通胡說八道,你應該了解了整個執(zhí)行流程咯?
那么繼續(xù)開一個引申
又一個小栗子
如果在finally中也有一個return,會發(fā)生什么?
public static void main(String[] args) { int result = test(); System.out.println(result); } public static int test() { int t = 0; try { return t; } finally { ++t; return t; } }
最終輸出的結(jié)果是1
就是說,如果try中有return而finally中也有return,那么后者將會讓前者失效!
理解
=> try中將t保留了一份副本用于返回出去,到了finally中,又有一個return語句,這時候又要創(chuàng)建一個用于返回的副本,那這個時候就有兩個副本了,到底返回誰呢?取后者!
總結(jié)
這一個面試題,看似簡單,卻暗藏殺機?。?/p>
可是說了這么多,結(jié)果就是finally在return之后執(zhí)行嗎?
非也,你沒看見return沒有真正的執(zhí)行完就開始執(zhí)行finally嗎?并且是先執(zhí)行完了finally,才執(zhí)行完return,這也就很好理解java規(guī)范中的finally在return之前執(zhí)行了。
不過,按如上情況,這句話應該變成這樣:finally比return先執(zhí)行完畢。是不是就更容易理解了呢?
也就是說,return先被執(zhí)行了,執(zhí)行return的時候發(fā)現(xiàn)有finally,于是不能那么快執(zhí)行完畢return,先去執(zhí)行finally,等finally執(zhí)行完畢之后,return才能執(zhí)行完畢。
上述內(nèi)容就是深入淺析java項目中return語句的執(zhí)行順序,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。