I started reading Java Concurrency in Practice and I came across the following example (this is a negative example - shows bad practice):
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
The author in the book writes:
When ThisEscape publishes the EventListener, it implicitly publishes the enclosing ThisEscape instance as well, because inner class instances contain a hidden reference to the enclosing instance.
When I think about the usage of such code, I could do something like so:
EventSource eventSource = new EventSource();
ThisEscape thisEscape = new ThisEscape(eventSource);
and I can get the reference to the registered EventListener, but what does it mean that I could obtain the reference to the enclosing ThisEscape instance?
Could someone give me an example of such a behaviour? What is the use case?
The problem with escaping this references is that code in other threads might start interacting with the object before the constructor is finished constructing it.
Consider this example:
public class ThisEscape
{
Foo foo;
public ThisEscape(EventSource source) {
source.registerListener(new EventListener()
{
public void onEvent(Event e) {
doSomething(e);
}
});
// Possible Thread Context switch
// More important initialization
foo = new Foo();
}
public void doSomething(Event e) {
// Might throw NullPointerException, by being invoked
// through the EventListener before foo is initialized
foo.bar();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With