2017-06-18 110 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(); 
    } 
}