面試被問finally 和 return,到底誰先執行?

經常有人面試被問到,finally 和 return,到底誰先執行呢?

為了解決這個問題,其實我們可以先想想 finally 是被用來幹嘛的呢?它是被用來結束一些正常的收尾動作或結束標識。也就是說無論怎麼樣,finally 都會被最後執行。例如:一般在操作數據庫時,用Jdbc連接池連接數據庫後釋放資源,需要 finally 來處理。再如 redis 連接,在獲取連接池處理完數據的增刪改查後,需要釋放其連接池。

面試被問finally 和 return,到底誰先執行?

但是,如果 return 是在 finally 前面呢?或者在 finally 後面呢?我們先來看看 return 在 finally 前面時,如:

<code>package com.test;

/**
*
*
* @author Damon
* @date 2020年3月18日 上午11:02:08
*
*/
public class App {
public static void main(String[] args) {
System.out.println("return result: " + test());
}

public static int test() {
try {
Thread.sleep(1);
System.out.println("執行 return 1");
return 1;// return 在try裡,則先執行,再執行finally後才有可能執行該return
}
catch (InterruptedException e) {
e.printStackTrace();
return -1;
}
finally {
System.out.println("執行 finally");
//return 3;
}
//System.out.println("執行 return 2");
//return 1;
}
}

結果:

執行 return 1
執行 finally
return result: 1
/<code>

也就是說,在執行 return 之前,先執行了 finally。

我們在看,如果 finally 前面有 return,在其內部也有 return:

<code>package com.test;

/**
*
*
* @author Damon
* @date 2020年3月18日 上午11:02:08
*
*/
public class App {
public static void main(String[] args) {
System.out.println("return result: " + test());
}

public static int test() {
try {
Thread.sleep(1);
System.out.println("執行 return 1");
return 1;// return 在try裡,則先執行,再執行finally後才有可能執行該return
}
catch (InterruptedException e) {
e.printStackTrace();
return -1;
}
finally {
System.out.println("執行 finally");
return 3;
}
//System.out.println("執行 return 2");
//return 1;
}
}

結果:

執行 return 1
執行 finally
return result: 3
/<code>

其內部被 return 後,就不再執行前面那個 return 了。

我們再來看 return 在 finally 之後,如:

<code>package com.test;

/**
*
*
* @author Damon
* @date 2020年3月18日 上午11:02:08
*
*/
public class App {
public static void main(String[] args) {
System.out.println("return result: " + test());
}

public static int test() {
try {
Thread.sleep(1);
//System.out.println("執行 return 1");
//return 1;// return 在try裡,則先執行,再執行finally後才有可能執行該return
}
catch (InterruptedException e) {
e.printStackTrace();
//return -1;
}
finally {
System.out.println("執行 finally");
//return 3;
}
System.out.println("執行 return 2");
return 1;
}
}

結果:

執行 finally
執行 return 2
return result: 1
/<code>

總結:finally 在 return 之後時,先執行 finally 後,再執行該 return;finally 內含有 return 時,直接執行其 return 後結束;finally 在 return 前,執行完 finally 後再執行 return。

接下來還有常被問到的是:Java 中 final、finally、finalize 的區別與用法:

  • final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。即如果一個類被聲明為 final,意味著它不能作為父類被繼承,因此一個類不能同時被聲明為 abstract 的,又被聲明為 final 的。變量或方法被聲明為 final,可以保證它們在使用中不被修改。被聲明為 final 的變量必須在聲明時給賦予初值,而在以後的引用中只能讀取,不可修改。被聲明為 final 的方法也同樣只能使用,不能重載。
  • finally 是異常處理語句結構的一部分,總是執行,常見的場景:釋放一些資源,例如前面所說的 redis、db 等。在異常處理時提供 finally 塊來執行任何清除操作,即在執行 catch 後會執行 finally 代碼塊。
  • finalize 是 Object 類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。

歡迎加微信公眾號程序猿Damon,一起討論Spring cloud 源碼、微服務架構設計、k8s實戰、kubeEdge邊緣計算框架等。

本文由博客群發一文多發等運營工具平臺 OpenWrite 發佈


分享到:


相關文章: