This was asked slightly differently earlier but asking for a yes/no answer but I\'m looking for the explanation that\'s missing from the book (Java Concurrency in Practice),
The key point here is that it is often easy to forget that an in-lined anonymous object still has a reference to its parent object and that's how this code fragment is exposing a not-yet-completely-initialised instance of itself.
Imagine EventSource.registerListener
immediately calls EventLister.doSomething()
! That doSomething
will be called on an object whose parent this
is incomplete.
public class ThisEscape {
public ThisEscape(EventSource source) {
// Calling a method
source.registerListener(
// With a new object
new EventListener() {
// That even does something
public void onEvent(Event e) {
doSomething(e);
}
});
// While construction is still in progress.
}
}
Doing it this way would plug the hole.
public class TheresNoEscape {
public TheresNoEscape(EventSource source) {
// Calling a method
source.registerListener(
// With a new object - that is static there is no escape.
new MyEventListener());
}
private static class MyEventListener {
// That even does something
public void onEvent(Event e) {
doSomething(e);
}
}
}