2013-06-01 27 views
1

此引用在構造問題期間是否轉義(如Brian Goetz和其他人在Java中的實踐中所稱的)會影響單線程程序或多線程程序?我的意思是,如果我的類不應該是線程安全的,可以讓這個引用在構造過程中逃脫嗎?此參考轉義單線程程序

編輯:例如,在這裏:

public class ThisEscape { 
    public ThisEscape(EventSource source) { 
     source.registerListener(
      new EventListener() { 
       public void onEvent(Event e) { 
        doSomething(e); 
       } 
      }); 
    } 
} 

EDIT2:我的問題的動機是插件的WindowBuilder爲Eclipse創建(或似乎產生了...)在一個JFrame的構造作用聽衆和默認將匿名類傳遞給那些,從而允許這個引用轉義...

+0

如果您在問題中包含您提到的部分,則會更好。 – Keppil

回答

2

允許「this」引用轉義不一定會導致問題。它可以解決問題,但它完全取決於其他代碼如何處理它。

那麼,爲什麼不在構造函數中泄漏這個最佳實踐呢?如果EventSource在寄存器函數中立即發送「now connected」事件怎麼辦?怎麼了? doSomething()被調用(並且介意你,你仍然是中間構造函數,可能不會初始化對象)。這完全取決於該方法的作用,但以下情況之一是正確的:

  1. doSomething中所需的所有東西都在偵聽器註冊之前初始化,並且事情能夠解決。
  2. 東西是空的,你不理它,從而導致意外結果
  3. 東西炸燬的東西結果爲空時,它不應該是(NPE或類似)。

但是,你說,它不發送該事件。所以你沒事吧?那麼,直到其他人改變它,並開始發送類似的東西,然後你自發地破壞而不直接改變你的代碼。

簡寫:如果可以的話,請避免這樣做;它會引起頭痛。如果您絕對必須出於某種原因,請注意您在泄漏之前初始化所有可能的事項,並且要非常小心地瞭解將要發生的事情,並意識到未來可能出現的問題。

3

一般來說,你不應該嘗試使用你的對象,直到它被完全構造。如果在完全初始化之前將對象傳遞給其他代碼,除非您非常小心,否則可能會導致混淆結果。即使在單線程程序中。

這就是說,有時候它不是問題,尤其是如果你知道該對象將在稍後纔會被使用。

1

不要這樣做。在施工之前讓參考文件轉義可能導致未指定的行爲。使用靜態工廠模式,讓你的憂慮休息,多線程或不

在您的例子就應該是這樣的:

public class ThisEscape{ 
    private final EventListener listener; 

    private ThisEscape(){ 
    listener = new EventListener(); 
    } 

    public static public ThisEscape makeEscape(EventSource source){ 
    ThisEscape e = new ThisEscape(); 
    source.registerListener(e.listener); 
    return e; 
    } 

    private class EventListener{ 
    public void onEvent(Event e){ 
     doSomething(e); 
    } 
    } 
} 

顯然靜態工廠不允許無縫類擴展,但在根據我的經驗,這通常不是問題,即使需要製造一些工廠方法。

此代碼對於構造而言是線程安全的;一定要介意,你班的其他人是線程安全的。