finally語句的執行有一定前提,需執行到try語句。如果在try語句之前就返回,finally語句必然不會執行。此外,在執行try語句過程中,終止JVM也不會執行finally語句。所以,在finally語句塊執行的前提下,討論finally語句到底在return之前還是之後呢? 在這裏分了以下幾種情況來分析:
1.情況1,就是try中的return語句先執行但並沒有立即返回,其次finally塊中的語句執行,最後try中return返回。
public class Test {
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
int num = 10;
try {
System.out.println("try doing...");
return num += 10;
}catch (Exception e){
System.out.println("catch doing...");
}finally {
System.out.println("finally doing...");
if (num > 15){
System.out.println("num > 15, num = " + num);
}
}
return 100; //不可達
}
}
運行結果:
try doing...
finally doing...
num > 15, num = 20
20
其過程是,try中的return語句num += 10先執行,num = 20,但該return語句沒有將結果直接返回,而是執行finally語句塊的語句,打印“finally doing…”,以及if語句打印“num > 15, num = 20”,執行完finally塊內容。最後,return返回try中的結果。(在此說下,Java中到底是傳值還是傳址?詳情見)
2.情況2,finally中的return語句會覆蓋try中return的結果
public class Test {
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
int num = 10;
try {
System.out.println("try doing...");
return num += 10;
}catch (Exception e){
System.out.println("catch doing...");
}finally {
System.out.println("finally doing...");
if (num > 15){
System.out.println("num > 15, num = " + num);
}
return 30;
}
}
}
運行結果:
try doing...
finally doing...
num > 15, num = 20
30
其過程是,try中的return語句num += 10依舊先執行,num = 20,該return語句沒有將結果直接返回,繼續執行finally語句塊的語句,打印“finally doing…”,以及if語句打印“num > 15, num = 20”,後執行finally中的return語句並將30作爲結果返回,從而造成了try中返回的結果num=20被覆蓋。
3.情況3,如果finally語句中沒有return語句覆蓋返回值,那麼原來的返回值是否會改變?
其實這與Java參數傳遞方式是相似的(均爲值傳遞),“返回值”均不會改變,這裏的“返回值”有兩層含義。
如果返回的是基本數據類型,沒有return語句覆蓋返回值時,原來的返回值不會改變。注意,此處的返回值指的是 try語句塊 中變量num所指向的存儲單元的內容。(num = 20,返回的是20)。
public class Test {
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
int num = 10;
try {
System.out.println("try doing...");
return num += 10; //返回的是num所對應存儲單元的內容,即20
}catch (Exception e){
System.out.println("catch doing...");
}finally {
System.out.println("finally doing...");
if (num > 15){
System.out.println("num > 15, num = " + num);
}
num = 100;
System.out.println(num);
}
return 0;
}
}
運行結果:
try doing...
finally doing...
num > 15, num = 20
100
20
返回的是引用數據類型,沒有return語句覆蓋返回值時,原來的返回值也不會改變。注意,此處的返回值指的是 try語句塊中 引用變量sb所指向的存儲單元的內容,內容是對象的地址值。
public class Test {
public static void main(String[] args) {
System.out.println(test().toString()); //4. 訪問的是0x0001所指的對象
}
public static StringBuffer test(){
StringBuffer sb = new StringBuffer("Kyrie");//1. 假設0x0001是創建的對象地址值
try {
System.out.println("try doing...");
return sb; //2. sb->0x0001,返回的是sb所對應存儲單元的內容,即0x0001
}catch (Exception e){
System.out.println("catch doing...");
}finally {
System.out.println("finally doing...");
sb.append("2011");
sb = new StringBuffer("6666"); //3. 此處,相當於sb指向了一個新對象,新對象的地址值爲0x1000,那麼sb所指存儲單元內容爲0x1000
System.out.println(sb.toString());
}
return null;
}
}
運行結果:
try doing...
finally doing...
6666
Kyrie2011
4.情況4,try塊裏的return語句在異常的情況下不會被執行
public class Test{
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
int num = 10;
try {
System.out.println("doing try。。。");
num = num / 0;
return num += 100; //不會被執行
}catch (Exception e){
num += 10;
System.out.println("doing catch, num = " + num);
}finally {
if (num > 15){
System.out.println(" num > 15, num = " + num);
}
}
return -1;
}
}
運行結果:
doing try。。。
doing catch, num = 20
num > 15, num = 20
-1
從上述結果可看出,try中發生的異常時,try中的return語句不會被執行。
5.情況5,當發生異常後,catch中的return執行情況與未發生異常時try中return的執行情況完全一樣
public class Test {
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
int num = 10;
try {
System.out.println("doing try。。。");
num = num / 0;
return num += 100;
}catch (Exception e){
System.out.println("doing catch, num = " + num);
return num += 40; //先執行 num+=40,此時num所指向的存儲單元的內容爲40
}finally {
if (num > 15){
System.out.println(" num > 15, num = " + num);
}
num += 1000;
}
}
}
運行結果:
doing try。。。
doing catch, num = 10
num > 15, num = 50
50
過程是發生異常後,catch中的return語句先執行,確定了返回值後再去執行finally塊,執行完後catch中的return再返回結果,finally裏對num的改變對返回值無影響,原因同前面一樣,也就是說情況與try中的return語句執行完全一樣。