52

Why do IDE's complain about "leaking this in constructor"? I've always assumed that it's just bad practice. But I actually never found why it is bad.

mmohaveri
  • 528
  • 7
  • 23
Reinard
  • 3,624
  • 10
  • 43
  • 61
  • Have a look at http://stackoverflow.com/questions/3921616/java-leaking-this-in-constructor – Chetter Hummin Mar 24 '12 at 12:39
  • FWIW, there is actually a theoretical JVM security hole if `this` is leaked very early in the constructor. But the JVM (supposedly) assures you can't leak it that early. – Hot Licks Jul 03 '13 at 17:59

2 Answers2

89

Leaking the this reference in the constructor (not controller) is dangerous, especially in a multithreaded environment. This is because the object is not fully constructed until the constructor call finishes. Leaking this from the constructor thus means that the external world gets access to an object which is not yet fully constructed. This may not necessarily lead to problems in a a single-threaded program (although it is possible, but the problem is much more obvious in this case). But if this is leaked to other threads, they can actually try to do something with the object before its construction is finished, which leads to subtle and hard to find bugs.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 4
    Could someone please create and attach a "best-practice" tag to this post, please? – user1050755 Mar 10 '13 at 22:40
  • 4
    What would be an example of an issue with leaking `this` in a single-threaded program? – WaelJ Jul 03 '13 at 23:47
  • @WaelJ class `A` creates an object of class `B` in its constructor and passes itself to it, while the object of class `B` now takes this object and calls some methods. The bug is now much more obvious and can easily be debugged, but it is an example that can be easily reproduced. – benez Jan 20 '22 at 19:07
18

There are few absolutes in life, eg. you must pay taxes ... or ... death is inevitable. But "passing this out of a constructor is always bad" is -not- one of them.

The caveats pointed out by Peter are all apt and valid. It would certainly be problematic to leak this from a constructor into any method or context in which the reference would become published to unknown or untrusted clients. It is still bad to publish a reference for a not-yet-fully-constructed object to any client code, trusted or not, that operates with the assumption that it will have a view to a valid and consistent object.

That said, there is absolutely nothing wrong with passing this from a constructor to a package-private method that performs a common initialization on, say, a group of objects that share a common interface, particularly if that initialization is lengthy or complex.

TL;DR: There are certainly some situations in which, in my opinion, it is not only acceptable to pass this from a constructor, but actually desirable to do so.

scottb
  • 9,908
  • 3
  • 40
  • 56
  • 17
    Just don't do it. We just wasted days working around a bug created years ago when someone passed 'this' out of a constructor to a 'trusted' "package private" method. Over time, that method ended up growing, and the un-initialized instance got into an event queue. Just use a final init() after construction, and be an anonymous hero. – Charlweed Sep 13 '15 at 20:52