I got E08250 THIS_ESCAPES_CONSTRUCTOR — why can't I pass 'this' out of a constructor?
← Concurrency · Ref: Q1349
E08250 fires when a constructor passes `this` as an argument to another method or function before construction has finished. The object is only partially built at that point — its fields may still be unset — so letting a reference escape lets other code (or another thread) observe a half-initialised object. This is the classic 'unsafe publication' bug that causes intermittent NullPointer-style failures and data races.
WHAT THE ERROR MEANS
Inside a constructor body, `this` is still being assembled. Handing it to `reg.register(this)`, storing it in a collection owned by someone else, or capturing it into a function that outlives the constructor all let the not-yet-finished object be used. EK9 rejects any `this` argument inside a constructor body.
HOW TO FIX
Complete construction first, then register. Move the escaping call OUT of the constructor into a separate step the caller performs after the object exists, or use a factory function that constructs the object fully and only then registers it.
publisher <- Publisher("news") //fully constructed registry.register(publisher) //register afterwards — safe
WHY EK9 DETECTS THIS
Unsafe publication is invisible in most languages — Java, C#, and C++ all let `this` escape a constructor with no warning, and the resulting races only surface under load. EK9 forbids it structurally so a reference to a half-built object can never be observed.
Example
defines module qa.concurrency.this.escapes.constructor defines class Registry items as List of Publisher: List() of Publisher default Registry() register() -> p as Publisher items += p count() as pure <- rtn as Integer: length items default operator ? Publisher name as String: String() Publisher() -> n as String reg as Registry this.name: n stdout <- Stdout() stdout.println(`registry size ${reg.count()}`) default operator ?
Common mistakes
E08250 — The constructor passes `this` to `reg.register(this)` before the Publisher is fully built, letting a half-initialised object be observed (and, across threads, raced on). The fix is to finish construction and register afterwards from the caller, or via a factory. See ek9 -h E08250.
Incorrect:
reg.register(this)
Correct:
stdout <- Stdout() stdout.println(`registry size ${reg.count()}`)
Other ways to ask this
- Why does EK9 reject passing this in a constructor?
- How to register an object during construction in EK9?
- this escapes constructor error E08250
- Publishing this from a constructor body EK9
Coming from another language?
Java/C#/C++: `this` may escape a constructor freely; escape analysis tools flag only some cases and the resulting races are load-dependent. EK9: any `this` argument inside a constructor body is a compile-time error, eliminating unsafe publication entirely.
Keywords: initialisation, unsafe, register, escapes, safe, half-built, this, publication, race, E08250, constructor