隐式使用This 引述逸出

隐式使用This 引用逸出

  在 《Java Concurrency in Practice》中关于隐式使用This 引用逸出的示例,比较难以理解如何逸出。最这个个人的理解代码是:

/**
 *
 * @author zhangwei_david
 * @version $Id: ThisEscape.java, v 0.1 2014年11月3日 上午9:37:54 zhangwei_david Exp $
 */
public class ThisEscape {
    private String name = null;

    public ThisEscape(EventSource source) {
        source.registerListener(new EventListener() {

            public void onEvent(Event event) {
                doSomething(event);
            }

        });
        name = "TEST";
    }

    /**
     *
     * @param event
     */
    protected void doSomething(Event event) {
        System.out.println(name.toString());
    }
}
import java.awt.Event;

/**
 * 
 * @author zhangwei_david
 * @version $Id: Listener.java, v 0.1 2014年11月3日 上午9:40:13 zhangwei_david Exp $
 */
public interface EventListener {
    public void onEvent(Event event);

}

 

/**
 *
 * @author zhangwei_david
 * @version $Id: EventSource.java, v 0.1 2014年11月3日 上午9:38:40 zhangwei_david Exp $
 */
public class EventSource {

    public void registerListener(EventListener listener) {
        listener.onEvent(null);
    }

}

 

/**
 *
 * @author zhangwei_david
 * @version $Id: Client.java, v 0.1 2014年11月3日 上午9:45:48 zhangwei_david Exp $
 */
public class Client {

    /**
     *
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        EventSource es = new EventSource();
        new ThisEscape(es);

    }

}

 运行的结果是:

Exception in thread "main" java.lang.NullPointerException
	at com.cathy.demo.concurrency.escape.ThisEscape.doSomething(ThisEscape.java:33)
	at com.cathy.demo.concurrency.escape.ThisEscape$1.onEvent(ThisEscape.java:21)
	at com.cathy.demo.concurrency.escape.EventSource.registerListener(EventSource.java:15)
	at com.cathy.demo.concurrency.escape.ThisEscape.<init>(ThisEscape.java:18)
	at com.cathy.demo.concurrency.escape.Client.main(Client.java:21)

  这个就是由于在name 初始化之前,就使用了ThisEscape实例,而此时实例尚未完成初始化。

 同样修改SafeListener

import java.awt.Event;

/**
 *
 * @author zhangwei_david
 * @version $Id: SafeListener.java, v 0.1 2014年11月3日 上午10:20:26 zhangwei_david Exp $
 */
public class SafeListener {

    private final EventListener listener;
    private String              name = null;

    private SafeListener() {
        listener = new EventListener() {

            public void onEvent(Event event) {
                doSomething();
            }
        };
        name = "TEST";
    }

    public static SafeListener newInstance(EventSource eventSource) {
        SafeListener safeListener = new SafeListener();
        eventSource.registerListener(safeListener.listener);
        return safeListener;
    }

    /**
     *
     */
    protected void doSomething() {
        System.out.println(name.toString());
    }
}
/**
 *
 * @author zhangwei_david
 * @version $Id: Client.java, v 0.1 2014年11月3日 上午9:45:48 zhangwei_david Exp $
 */
public class Client {

    /**
     *
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        EventSource es = new EventSource();
        //        new ThisEscape(es);
        SafeListener.newInstance(es);
    }

}

 结果是:

TEST