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条)

报告相同问题?

悬赏问题

  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型