《java并发编程实战》里面有段代码,原来看的时候稍微有点不清楚,最近随手翻,突然看见了,遂记录一下。
先看代码
public class ThisEscape {
public ThisEscape(EventSource source){
source.registerListener(
new EventListener(){
public void onEvent(Event e){
doSomething()e;
}
});
}
}
这段代码的问题是对象逸出。
当ThisEscape发布EventListener时,也隐含地发布了ThisEscape实例本身,因为这个内部类的实例中包含了对ThisEscape实例的隐含引用。(注意是内部类)
因为,当我们声明一个内部类时,编译器会添加对外部类的一个隐式引用,该对象引起内部类对象的构造,该对象引起内部类对象的构造。如果外部类的名字为Outer,那么隐式引用就是Outer.this。
上述代码是一个构造方法,构造方法是用来创建对象的,但是构造方法里面有内部类,内部类有隐式引用,也就是说外部类在构造过程中被其构造方法里的内部类引用了,本身构造过程还没完就引用了自己肯定是有问题的。
书中给了解决方法,使用工厂方法防止this引用在构造过程中逸出。
public class SafeListener {
private final EventListener listener;
private SafeListener(){
listener = new EventListener(){
public void onEvent(Event e){
doSomething(e);
}
}
}
public static SafeListener newInstance(EventSource source){
SafeListener safe = new SafeListener();
source.registerListener(safe.listener);
return safe;
}
}
与此类似的还有,在构造方法中新启线程,使用线程可以,注意不要执行start()方法,否则会逸出。