Allowing the this reference to escape
Solution 1:
It means calling code outside the class, and passing
this
.
That code will assume that the instance is fully initialized, and may break if it isn't.
Similarly, your class might assume that some methods will only be called after the instance is fully initialized, but the external code is likely to break those assumptions.final
methods cannot be overridden, so you can trust them to not passthis
around.
If you call any non-final
method in the constructor for a non-final
class, a derived class might override that method and passthis
anywhere.
Even when you callfinal
methods, you still need to make sure that they are safely written – that they do not passthis
anywhere, and that themselves don't call any non-final
methods.
Solution 2:
"Escape" means that a reference to the partially-constructed this
object might be passed to some other object in the system. Consider this scenario:
public Foo {
public Foo() {
setup();
}
protected void setup() {
// do stuff
}
}
public Bar extends Foo implements SomeListener {
@Override protected void setup() {
otherObject.addListener(this);
}
}
The problem is that the new Bar
object is being registered with otherObject
before its construction is completed. Now if otherObject
starts calling methods on barObject
, fields might not have been initialized, or barObject
might otherwise be in an inconsistent state. A reference to the barObject
(this
to itself) has "escaped" into the rest of the system before it's ready.
Instead, if the setup()
method is final
on Foo
, the Bar
class can't put code in there that will make the object visible before the Foo
constructor finishes.