2012-03-24 51 views
29

爲什麼IDE會抱怨「在構造函數中泄漏這個」?我一直認爲這只是不好的做法。但我從來沒有發現它爲什麼壞。Java在構造函數中泄漏這個

+0

看看http://stackoverflow.com/questions/3921616/java-leaking-this-in-constructor – 2012-03-24 12:39:03

+0

FWIW,實際上有一個理論上的JVM安全漏洞,如果'this'在構造函數中很早泄漏。但是JVM(據說)確保你不會那麼早泄漏它。 – 2013-07-03 17:59:37

回答

56

泄漏this參考構造函數(不是控制器)是危險的,特別是在多線程環境中。這是因爲在構造函數調用完成之前對象沒有完全構造。因此從構造函數泄漏this意味着外部世界可以訪問尚未完全構建的對象。這可能不一定會導致單線程程序中的問題(儘管這是可能的,但在這種情況下問題更加明顯)。但是,如果this泄露給其他線程,他們實際上可以嘗試在構建完成之前對對象執行某些操作,這會導致細微且難以發現的錯誤。

+2

有人可以創建並附上一個「最佳實踐」標籤到這個職位,請? – user1050755 2013-03-10 22:40:54

+2

在單線程程序中泄漏'this'會出現什麼樣的問題? – WaelJ 2013-07-03 23:47:26

7

生命中的絕對數量很少,例如。你必須交稅......或者......死亡是不可避免的。但是「從構造函數中傳遞this始終是不好的」不是其中之一。

彼得指出的警告都是恰當和有效的。將this從構造函數泄漏到引用將發佈到未知或不可信的客戶端的任何方法或上下文中肯定會有問題。將尚未完全構建的對象的引用發佈到任何可信或不可信的客戶端代碼上仍然很糟糕,該代碼的操作假定它將有一個有效且一致的對象視圖。

也就是說,將this從構造函數傳遞給一個包 - 私有方法是絕對沒有錯誤的,該方法對共享一個公共接口的一組對象執行通用初始化,特別是如果初始化過長或複雜。

TL; DR:當然有些情況下,我認爲不僅可以從構造函數中通過this,而且實際上也可以這樣做。

+6

只是不這樣做。我們浪費了幾天的時間來解決幾年前創建的一個bug,當時有人將「this」從構造函數傳遞到「trusted」「package private」方法。隨着時間的推移,這種方法結束了,未初始化的實例進入事件隊列。只需在構建完成後使用最終的init(),併成爲匿名的英雄。 – Charlweed 2015-09-13 20:52:04