Effective Java Item 7 note

Avoid finalizer

Arwii
mycodingjourney
2 min readMay 25, 2018

--

finalizer通常是不可預測的,最好不要使用。

Java主要是用GC來處理記憶體回收相關事宜,所以也沒有類似C++的destructor的東西出現

finalizer最主要的缺點就是他不能保證會及時地被執行,從一個object被移除全部的reference開始到finalizer被執行的這段時間是任意長度的,如果受到時效性影響的行為是不能用finalizer來執行的。例如:用finalizer去關閉已經打開的file,可能會因為還沒跑到finalizer影響到下次有需要打開file的時候。

然後因為finalizer會倚靠JVM的GC演算法設計而有所不同,所以在不同JVM上面可能會有不同的結果。

而Java不但不保證finalizer會及時被執行,也不保證一定會執行,有可能一個process結束了但已經無法access的object的finalizer根本沒有被執行。除了最好不要用finalizer之外也不要依靠finalizer來更新狀態等等的動作。

雖然有System.gc 跟System.runFinalization這兩個method,只是增加finalize的機會而已。

發生在finalizer裡面的crash並不會丟出異常然後也不會看到stack trace,效能使用也不好。

那如果一定有東西需要被中止的話,那你應該提供一個public的method讓呼叫者去使用,然後也要在該class中管理這個狀態,如果是在終止後還使用該class的功能則要去做相關處理之類的,例如丟出exception。

那finalizer什麼時候會用到呢?

  1. 如果用戶沒有使用提供的結束方法,避免不釋放資源的時候可能是最後一個如果有用的話就好了的方法了。不過如果是這種情況,也是要再加一個log讓用戶知道是這種情形。
  2. 另一種使用的情況就是可以用來回收native method的物件了,因為native物件JVM管不著。

然後:

finalize在java 9中已經被宣告是deprecate了

https://stuartmarks.wordpress.com/2017/04/17/deprecation-of-object-finalize/

可以看看Java 9裡面的新API

java.lang.ref.Cleaner

--

--

Arwii
mycodingjourney

Try not to become a man of success, but rather try to become a man of value — A. Einstein