java try finally返回值問題
阿新 • • 發佈:2018-11-29
需要知道的是:finally的語句會先於try或者catch的返回語句之前執行,如果finally中有return語句,那麼try或catch中的return語句會被finally中的return覆蓋,不建議在finally中放return
情況一:try、catch和finally中都有return
public static void main(String[] args) {
System.out.println(testInt());
}
private static int testInt(){
int a = 0;
try {
return a;
}catch (Exception e){
a = 9;
e.printStackTrace();
return a;
}finally {
a = 10;
return a;
}
}
最後輸出:
10
在try中的return執行之前,會執行finally中的語句,finally中有return,於是會覆蓋掉try中的return。如果此時發生了異常,catch中的return語句會執行嗎?看下面:
public static void main(String[] args) {
System.out.println(testInt());
}
private static int testInt(){
int a = 0;
try{
int b = 7/a; //產生了異常
return a;
}catch (Exception e){
a = 9;
e.printStackTrace();
return a;
}finally {
a = 10;
return a;
}
}
輸出結果:
10
java.lang.ArithmeticException: / by zero
at pattern.App.testInt(App.java:40)
at pattern.App.main(App.java:31)
產生了異常,catch中語句被執行,但是catch中的return執行之前會執行finally中的語句,所以catch中的return依然被覆蓋
情況二:try或者catch中有return,finally中沒有return
public static void main(String[] args) {
System.out.println(testInt());
}
private static int testInt(){
int a = 0;
try{
return a;
}catch (Exception e){
a = 9;
e.printStackTrace();
return a;
}finally {
System.out.println("執行finally");
a = 10;
}
}
輸出:
執行finally
0
可以看到,finally中的語句依然執行了,但是a的值在finally中改變了,返回值並沒有改變,如果這裡產生了異常呢?自然是會輸出9的(可以自己驗證一下),這裡可以看到對於基本型別a,finally的賦值並沒有改變返回值,如果是下面非基本型別的情況呢?
情況三:對於非基本型別
public static void main(String[] args) {
System.out.println(testNum().getNum());
}
private static Num testNum(){
Num num = new Num();
int a = 0;
try{
num.setNum(7);
return num;
}catch (Exception e){
e.printStackTrace();
num.setNum(9);
}finally {
num.setNum(10);
}
return num;
}
最後輸出結果:
10
同理如果是產生了異常,結果仍然是10(可以自己驗證)
可以看到,對於非基本型別,finally中的賦值最後在return中會被返回,通過看向志明《深入理解Java虛擬機器》第187頁講解“class檔案的屬性表”的時候,找到了為什麼:
- 不管什麼情況,finally中的語句總會執行(除非程式執行System.exit()),正常情況下載try後面執行,拋異常時載catch後面執行
- 對於返回值問題。try(或者catch)中的return語句的返回值放入執行緒棧的頂部:如果返回值是基本型別則頂部存放的就是值,如果返回值是引用型別,則頂部存放的就是地址。finally中的return語句可以修改引用所對應的物件,無法修改基本型別。所以情況二中的基本型別finally無法修改,但是情況三可以修改
- 不建議在finally中使用return