iteye_15201 2011-03-07 13:56
浏览 241
已采纳

关于”隐式允许this引用逸出“

在《Java Concurrency in Practice》中,对于发布对象和数据逸出有两种示例,
其中之一是:
Listing 3.6. Allowing Internal Mutable State to Escape. Don't Do this.

class UnsafeStates {
private String[] states = new String[] {
"AK", "AL" ...
};
public String[] getStates() { return states; }
}


这个好理解;

另外一个示例是:
Listing 3.7. Implicitly Allowing the this Reference to Escape. Don't Do this.

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

作者认为“it implicitly publishes the enclosing ThisEscape instance as well, because inner class instances contain a hidden reference to the enclosing instance.”

作者的改进建议是:

If you are tempted to register an event listener or start a thread from a constructor, you can avoid the improper construction by using a private constructor and a public factory method, as shown in SafeListener in Listing 3.8.

Listing 3.8. Using a Factory Method to Prevent the this Reference from Escaping During Construction.
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;
}

}



作者对于错误的原因是这样解释的:
ThisEscape illustrates an important special case of escapewhen the this references escapes during construction. When the inner EventListener instance is published, so is the enclosing ThisEscape instance. But an object is in a predictable, consistent state only after its constructor returns, so publishing an object from within its constructor can publish an incompletely constructed object. This is true even if the publication is the last statement in the constructor. If the this reference escapes during construction, the object is considered not properly constructed.
有谁能把这个原因解释清楚点,即:为什么说这是一个未完成的对象呢,一旦内部匿名类那段代码执行完后,对象不就被注册了么?
  • 写回答

4条回答

  • springof 2011-03-07 13:56
    关注

    首先,在之前我并不知道或已对this引用逸出这回事没有够印象。
    在看查看资料后,说说个人的理解,如理解有误还请见谅。

    对this逸出代码作部分修改,易于理解。
    原文:
    [code="java"]
    public class ThisEscape {
    public ThisEscape(EventSource source) {
    source.registerListener(
    new EventListener() {
    public void onEvent(Event e) {
    doSomething(e);
    }
    });
    }
    }[/code]

    修改后。

    [code="java"]
    public class ThisEscape {
    public ThisEscape(EventSource source) {
    source.registerListener(
    new EventListener() {
    public void onEvent(Event e) {
    doSomething(e);
    }
    });
    a
    ....b;
    ....c;
    ....d;
    }
    }[/code]

    在构造ThisEscape对象时,代码执行到a处时对事件的注册已经完成,而此时构造函数并没有完成。
    如正是这个时刻,事件发生,那么在doSomething中this是可见的。
    那么就出现了this逸出的问题。

    再次声明,本人也不知道理解是否正确。仅做参考。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?