Site Search:

SafeListener.java

 SafeListener.java

/**

 * SafeListener

 * <p/>

 * 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;

    }


    void doSomething(Event e) {

    System.out.println(e);

    }



    interface EventSource {

        void registerListener(EventListener e);

    }


    interface EventListener {

        void onEvent(Event e);

    }


    interface Event {

    }

}




class CopierEventSource implements SafeListener.EventSource {

    public CopierEventSource() {

        Thread a = new Thread(new Runnable() {

            @Override

            public void run() {

                while(!Thread.currentThread().isInterrupted()) {

                    try {

                        Thread.sleep(2000);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                    sendEvent();

                }

            }});

        this.a = a;

    }

    Thread a;

    SafeListener.EventListener el;

    

    public void startSender() {a.start();}

    

    @Override

    public void registerListener(SafeListener.EventListener e) {

        el = e;

    }

    

    private void sendEvent() {

        SafeListener.Event e = new SafeListener.Event() {

        };

        el.onEvent(e);

    }

}



public class ThisSafeListenerRunner  {

SafeListener.EventListener el;

    

    public ThisSafeListenerRunner(CopierEventSource source) {

    SafeListener safe = SafeListener.newInstance(source);

    System.out.println(source.el);

    el = source.el;

    }

    

    //SafeListener can not be subclassed, no longer able to override doSomething() to create stack overflow. 

    

    public static void main(String[] args) {

        CopierEventSource ces = new CopierEventSource();

        ces.startSender();

        new ThisSafeListenerRunner(ces);

    }

}