2017-06-18 53 views
4

我開始閱讀Java Concurrency in Practice和我碰到下面的例子來(這是一個反面的例子 - 顯示不好的做法):Java的逃逸參考「這」

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

書中的作者寫道:

當ThisEscape發佈EventListener時,它也會隱式地發佈封閉的ThisEscape實例,因爲內部類實例包含對封閉實例的隱藏引用。

當我想到這樣的代碼的使用,我可以做類似這樣:

EventSource eventSource = new EventSource(); 
ThisEscape thisEscape = new ThisEscape(eventSource); 

,我可以得到參考註冊事件監聽,但它是什麼意思,我可以得到包含ThisEscape實例的引用?

有人能給我一個這樣的行爲的例子嗎?什麼是用例?

+0

也許這可能是一個例子:https://stackoverflow.com/a/1084124/4563745 –

+0

好了,這是很好的使用情況,但我還是不明白這樣的轉義引用有什麼問題 - 即使我會做ThisEscape.this.doSomething();從匿名實現中,'this'仍然只在ThisEscape中可見。 – nibsa

+0

事件源可以在ThisEscape構造函數完成之前發送事件。事件將以處於不可預知狀態的對象進行處理。 – Joni

回答

0

轉義此引用的問題是其他線程中的代碼可能會在構造函數完成構造之前開始與對象進行交互。

考慮這個例子:

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

     // Possible Thread Context switch 

     // More important initialization 
     foo = new Foo(); 
    } 

    public void doSomething(Event e) { 
     // Might throw NullPointerException, by being invoked 
     // through the EventListener before foo is initialized 
     foo.bar(); 
    } 
}