「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


——下課後——

「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


public class Main {

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語句,確保會執行。


「漫畫」finally到底是在return之前執行還是return之後執行?




「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


  • 在某些情況下,try語句壓根就沒有執行到,那麼finally語句也一定就不會執行到了。
  • 還有一種情況就是在try塊中有System.exit(0);這樣的語句,System.exit(0);是終止Java虛擬機JVM的,連JVM都停止了,所有都結束了,當然finally語句也不會被執行到。


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


public class Main {

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;
}

}


執行結果

try
finally-i:10
finally
10



「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


代碼中try語句塊中,return i+=10; 這個時候i已經是10了,這個可以從輸出的打印結果看出來,因為進入到finally語句的時候,有一個打印語句,打印結果中i就是10,就說明了return語句中的i+=10是已經執行了。


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?



public class Main {

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;
}
}

}

執行結果

try
finally-i:10
finally
20


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?



在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返回之前執行的!


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


import java.util.ArrayList;
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;
}

}
/<string>/<string>/<string>


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


  • finally是在retrun語句執行後,return返回之前執行的,也就是說finally必執行(當然是建立在try執行的基礎上)
  • finally中修改的基本類型沒有return是不影響返回結果的,有了retrun才會影響
  • finally中修改list ,map,set引用類型時,就算沒有return,也是是影響返回結果的


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


「漫畫」finally到底是在return之前執行還是return之後執行?


作者: 喬戈裡qgl
原文:轉載自公眾號,程序員喬戈裡,已獲作者授權


分享到:


相關文章: