Java Magic. Part 3: Finally

来源:http://www.cnblogs.com/maxmys/archive/2016/02/06/5183964.html
-Advertisement-
Play Games

java magic翻譯系列文章,java小伙伴不知道的奇妙世界


Java Magic. Part 3: Finally

@(Base)[JDK, magic, 黑魔法]

轉載請寫明:原文地址

英文原文

系列文章:

-Java Magic. Part 1: java.net.URL
-Java Magic. Part 2: 0xCAFEBABE
-Java Magic. Part 3: Finally
-Java Magic. Part 4: sun.misc.Unsafe

所有JAVA程式員都應該知道一個基本概念-finally一定會被執行,但是真的是這樣麽?

這取決於“執行”是什麼意思。但總的來說答案都是,YES。

Normal program execution

有人可能拿如下的例子來反駁:

try {
  System.exit(1);
} finally {
  System.out.println("I'm here, man");
}

剛纔是不是你說的finlly塊一定會被執行。

顯然在上面這個例子中,Sout語句不會被執行。我們剛纔也說了,是正常的程式六層中答案是肯定的。

下麵這句話來自官方文檔

Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute.

我們再看下麵這段代碼,第二行是不是一定會執行呢?

Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute.

答案仍然是肯定的。除非...BANG...斷電了,程式終止。

這是神馬意思呢?意思就是程式非正常的運行。我們沒辦法保證所有事情。顯然,這和System.exit(1)是一個意思,也和你電腦上的重啟鍵是一個意思。

所以我們不討論這種情況啦。沒勁。

Perpetuum Mobile

永動機 我們再來看如下代碼:

try {
  while (true) {
    System.out.println("I print here some useful information");
  }
} finally {
  System.out.println("Let me run");
}

這裡的finlly塊會執行嗎?當然可能,就是在標準輸出異常的時候。但是絕大部分情況答案仍然是不會。

Threads

什麼是線程?我們都知道線程的執行流程可以被interrupted。

假設我們有一個線程正在執行一些東西,另外一個線程kill掉當前線程(此時他正要執行finally)。

還有一個場景是,如果兩個線程之間有死鎖,那麼還是不會執行finally塊的。

下麵這段話仍然來自官方文檔

...if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.

所以這種情況下,我們可以把線程當做一個獨立的程式來看:

Finally塊肯定是會執行的。除了程式或者線程異常的終止了。

Finally we return

好了,根據上述的文字,我們瞭解了finally一定會被執行。但是你知道finally什麼時候會被執行嗎?

考慮如下代碼:

int someFunc() {
  try {
    return 0;
  } finally {
    return 1;
  }
}

這個返回值是多少呢? 返回值是1。因為finally一定會被執行。

考慮下麵這段呢?

int someFunc() {
  try {
    throw new RuntimeException();
  } finally {
    return 1;
  }
}

答案仍然是1。但是有個問題是,異常就被吞掉了。這個場景是一個非常有名的場景,叫做exception swallowing。這是一個非常危險示例,因為client的代碼以為你會返回一個值或者拋出一個異常,但是你永遠都只是返回一個值。

下麵我們最後看一個類似的例子:

String deposit(int amount) throws DAOException {
  try {
    return dao.deposit(amount);
  } finally {
    return "OK";
  }
}

dao.deposit會拋出一個受檢的異常,導致客戶端必須處理這個異常,但是呢,由於上面我們已經提到的原因,這個函數又永遠返回OK,是不是有點淡淡的憂傷。

所以我們得到另外一個結論:

永遠不要在finally裡面使用return語句。

Instead of conclusion

很多程式員已經意識到finally的一些問題。但根據我們上面說的,只需要註意兩點就可以避免犯錯~

  • Rule 1 Finally executes always, except the case where controlling program or thread was aborted.
  • Rule 2 Never use return from finally block.

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 類的繼承,是在父類中存在可繼承的成員A,而在子類中不存在同名成員,這樣該成員會被繼承到子類,當子類對象訪問該成員時,實際訪問的是父類的對應成員。類的重寫,是在父類中存在可繼承的成員A,而在子類中存在同名成員,這樣該成員會被子類重寫,當子類對象訪問該成員時,實際訪問的是子類的成員。所以二者的區別就是,
  • 在節前的最後一天,解決了打包過程中遇到的所有問題,可以成功運行了!真是個好彩頭,希望新的一年一切順利! 以下是在使用cx_freeze過程中遇到的問題及解決辦法(Win7) 問題描述:運行exe,啟動無數個主程式,導致系統無法使用 原因:在程式中使用了multiprocessing的包 解決辦法:在
  • package CommonClassPart; import java.io.File; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class Common
  • /*漢諾塔的玩法: * 游戲的規則:將A柱上的盤子移動到C柱上,大盤必須在小盤之上。 * 1 當A柱上只有一個盤子的時候,直接移動到C柱上; * 2 當A柱上有兩個盤子的時候, * 將A柱上的1盤(從上到下編號)移動到B柱, * 將A柱上的2盤移動到C柱, * 將B柱上的1盤移動到C柱; * (將A
  • 本文實例講述了PHP限制HTML內容中圖片必須是本站的方法。分享給大家供大家參考。具體實現方法如下: 1. PHP代碼如下: <?php $dom = new DOMDocument; $dom->loadHTML(file_get_contents('input.html')); $xpath =
  • java magic翻譯系列文章,java小伙伴不知道的奇妙世界
  • package CollectionPart; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CollectionSort { public static v
  • 上一章記錄了幾種常見的垃圾收集器,見《第五章 JVM垃圾收集器(1)》 1、G1 說明: 從上圖來看,G1與CMS相比,僅在最後的"篩選回收"部分不同(CMS是併發清除),實際上G1回收器的整個堆記憶體的劃分都與其他收集器不同。 CMS需要配合ParNew,G1可單獨回收整個空間 原理: G1收集器將
一周排行
    -Advertisement-
    Play Games
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...
  • 1. JUnit 最佳實踐指南 原文: https://howtodoinjava.com/best-practices/unit-testing-best-practices-junit-reference-guide/ 我假設您瞭解 JUnit 的基礎知識。 如果您沒有基礎知識,請首先閱讀(已針 ...