Goetz的Java Concurrency in Practice,第41页提到了this在构造过程中引用如何逃脱.一个"不要这样做"的例子:
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
这this是通过doSomething(e)引用封闭ThisEscape实例的事实"逃避" .可以通过使用静态工厂方法(首先构造普通对象,然后注册侦听器)而不是公共构造函数(完成所有工作)来解决这种情况.这本书继续:
从构造函数中发布对象可以发布未完全构造的对象.这是真实的,即使是公布在构造函数中的最后一条语句.如果
this参考在构造期间逃逸,则认为该对象未正确构造.
我不太懂.如果发布是构造函数中的最后一个语句,那么之前没有完成所有构建工作吗?怎么会是this由当时不是有效?显然有一些伏都教在那之后继续,但是什么?
参考我之前关于不完整构造对象的问题,我有第二个问题.正如Jon Skeet指出的那样,在构造函数的末尾有一个隐式的内存障碍,可以确保final所有线程都可以看到这些字段.但是如果构造函数调用另一个构造函数呢?在每个人的最后是否有这样的记忆障碍,或者只是在第一个被召唤的人的最后?也就是说,当"错误"解决方案是:
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
正确的一个是工厂方法版本:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
以下工作是否也会起作用?
public class MyListener {
private final EventListener listener;
private …Run Code Online (Sandbox Code Playgroud)