一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java面試題之try中含return語句時代碼的執行順序詳解

java面試題之try中含return語句時代碼的執行順序詳解

2020-09-21 15:23LiuZh Java教程

這篇文章主要介紹了關于java中的一道面試題,這套題就是在try中含return語句時代碼的執行順序,這個問題看似簡單,卻暗藏殺機啊!文中通過一個個例子詳細介紹了其中玄機,需要的朋友可以參考學習,下面來一起看看吧。

前言

最近在刷java面試題偶然看到這類問題(try/finally中含有return時的執行順序),覺得挺有意思于是小小的研究了一下,希望經過我添油加醋天馬行空之后,能給你帶來一定的幫助,下面來看看詳細的介紹。

原題

try {} 里有一個return語句,那么緊跟在這個try后的finally {}里的代碼會不會被執行?什么時候被執行?在return前還是后?
乍一看題目很簡單嘛,java規范都說了,finally會在try代碼塊的return之前執行,你這文章寫得沒意義,不看了

你等等!(拿起我身邊的五尺砍刀)

神奇栗子

看完這個栗子,你在想想執行順序到底是怎樣的

栗子代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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()方法內,在try中return了t,那么在main方法中test()函數的返回值應該是t=0,即控制臺輸出0

但是因為有finally的存在,而finally中對t進行了自增運算,并且finally會在try中的return語句之前執行,所以正確的情況是控制臺輸出1

所以你最終確定的答案是:控制臺輸出1

然而事實并非如此,將程序跑起來之后,得到的結果是:

輸出0

將栗子跑起來親眼看一下吧~

得到這個結果你也許要爆炸了,啥?java規范說的都是錯的?!

不用急,到我給sun洗地的時間了

洗地時間

在洗地之前,你很有必要先理解java中的值傳遞,如果你已經了解該內容可略過下面這一個小節點

java中的值傳遞

由于這只是本文內容引申出去的知識點,不過多贅述,隨便嘮兩句,能借此明白則好,不明白希望借助搜索引擎明白一下!
在java的方法調用中,時常需要傳遞參數,那么傳遞的參數是將之前的變量直接傳遞給方法內了嗎?

顯然不是的,調用方法傳遞參數的時候,傳遞的只是原變量的一個副本(復制體),換句話說就是,將變量的值傳遞給了方法體,而并沒有真正的將變量傳遞進去。

看個栗子:

?
1
2
3
4
5
6
7
8
9
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()方法內拿到的a,只是t的一個副本(復制體)而并不直接是t,test()內改變了a的值,并不影響t的值

以上是對于基本數據類型,如果對于對象呢?

如果參數是對象,那么傳遞的是對象的引用的副本(復制體),這也就是為什么在方法體內對對象進行修改,會真正的改變對象。因為方法體外的引用和方法體內的引用指向的是堆內存中的同一個對象,傳遞的是對象的引用

如果這里還不能理解值傳遞,建議先理解一下這一個概念再繼續往下看

真的開始分析了

為了你看著方便,栗子代碼再來一份:(我真的不是為了湊字數)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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;時,并不是直接將t返回了出去,而是將t保留了起來(因為還有一個finally語句塊沒有執行!)并且這個保留,就是值傳遞性質的一個保留,也就是保留的是t的一個副本(復制體),我這里先叫他tt吧(不是套套!!)
  • 接下來執行finally語句塊,finally中將t做了自增運算,t的確變成了1,但是這并沒有影響t的復制體tt的值!保留起來的tt值還是0!
  • 這個時候執行完了finally,正式將保留起來的tt返回出去,于是,整個函數的返回結果就是0
  • 這個t的副本(復制體)保留的地方是哪兒呢?我查了半天,有個應該靠譜的說法,保留在函數棧中,但具體保留的區域叫什么,我也不知道,還請知情大佬指教一下!

上圖或許直觀一點?

java面試題之try中含return語句時代碼的執行順序詳解

那么如果,這個t是一個對象呢?按照前面說的值傳遞的問題,如果t是一個對象,在finally中對t進行修改,那么最終返回出去的t所顯示出來的數據,應該是經過修改的。

寫一個Person類來檢驗一下吧

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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是一個對象的引用,對象實例保存在堆內存中,t的副本tt也是一個對象的引用,t和tt都指向堆內存中的對象實例,那么不論修改誰,實際上對象實例都被修改了!

看完我這一通胡說八道,你應該了解了整個執行流程咯?

那么繼續開一個引申

又一個小栗子

如果在finally中也有一個return,會發生什么?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}
}

最終輸出的結果是1

就是說,如果try中有return而finally中也有return,那么后者將會讓前者失效!

理解

=> try中將t保留了一份副本用于返回出去,到了finally中,又有一個return語句,這時候又要創建一個用于返回的副本,那這個時候就有兩個副本了,到底返回誰呢?取后者!

總結

這一個面試題,看似簡單,卻暗藏殺機啊!

可是說了這么多,結果就是finally在return之后執行嗎?

非也,你沒看見return沒有真正的執行完就開始執行finally嗎?并且是先執行完了finally,才執行完return,這也就很好理解java規范中的finally在return之前執行了。

不過,按如上情況,這句話應該變成這樣:finally比return先執行完畢。是不是就更容易理解了呢?

也就是說,return先被執行了,執行return的時候發現有finally,于是不能那么快執行完畢return,先去執行finally,等finally執行完畢之后,return才能執行完畢。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://juejin.im/post/5901cefa44d90400690cd3d4

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久久精品免费视频 | 国产香蕉97碰碰久久人人 | 国内精品久久久久久野外 | 精品国产乱码久久久久久软件 | 国内精品自产拍在线观看91 | 91美女在线 | 欧美一区精品 | 天美蜜桃精东乌鸦传媒 | 蜜桃视频在线观看官网 | 国产果冻传媒 | 色综合色狠狠天天久久婷婷基地 | 91麻豆精品国产 | 免费人成黄页在线观看69 | 欧美又黄又激烈真实床戏 | 国产乱插 | 边摸边操| 国内精品伊人久久大香线焦 | 亚洲欧美精品天堂久久综合一区 | 国产91素人搭讪系列天堂 | 成人国产午夜在线视频 | 北条麻妃黑人 | 91香蕉视频在线观看 | 亚洲国产精品综合欧美 | 精品国产91久久久久久久 | 双性太子| 天天摸天天爽视频69视频 | 好看华人华人经典play | 全黄毛片| 亚洲国产在线播放 | 特黄视频| 亚洲国产成人久久综合一 | 国产尤物精品视频 | 男人好大好硬好爽免费视频 | 亚洲国产天堂在线观看 | 给我免费观看的视频在线播放 | 美女gif趴跪式抽搐动态图 | 男男同志gaysxxx | 亚洲欧美国产另类 | 亚洲人和日本人hd | 色综合视频在线 | 很黄的孕妇a级黄毛片 |