E05050: 'this()' and 'super()' must be the first statement in a constructor
What went wrong
Calls to this() or super() must be the FIRST statement in a constructor. You have code executing before the constructor delegation call. This violates the initialization order requirement.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 582 (Why must this() or super() be the first statement in a co...)
- ek9 -q 580 (How do I call one constructor from another using this()?)
- ek9 -q 581 (How do I call a parent constructor using super()?)
- ek9 -q 583 (Can I use both this() and super() in the same constructor?)
- ek9 -q 584 (When is an explicit super() call required?)
How to fix it
- Move this() or super() to be the very first statement
- Any parameter validation must come AFTER the delegating call
- If validation must happen first, do it in the delegated constructor
Rationale
This rule ensures:
- Object is properly initialized before any other code runs
- Parent class state is established before child accesses it
- Field initialization order is consistent and predictable
Common causes
- Wanting to validate parameters before delegation
- Copying patterns from languages with different rules
- Refactoring that moved statements around
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E05050: 'this()' and 'super()' must be the first statement in a constructor
#!ek9 defines module error.e05050.bad defines class Base as open label as String: "base" Base() -> label as String this.label: label default operator ? Derived extends Base extra as String: "derived" Derived() -> label as String super(label) //Construction delegates once, first: a second call is not first super(label) Derived() -> label as String extra as String this.extra: extra this(label) default operator ?
Fixed: Call super(...) or this(...) once, as the first statement; other work follows it
#!ek9 defines module error.e05050.good defines class Base as open label as String: "base" Base() -> label as String this.label: label default operator ? Derived extends Base extra as String: "derived" Derived() -> label as String super(label) Derived() -> label as String extra as String this(label) this.extra: extra default operator ?
Questions and answers
These Q&A entries show E05050 and its fix:
- Q580: How do I call one constructor from another using this()?
- Q581: How do I call a parent constructor using super()?
- Q582: Why must this() or super() be the first statement in a constructor?
- Q583: Can I use both this() and super() in the same constructor?
- Q584: When is an explicit super() call required?
- Q586: How does constructor delegation work with pure constructors?
- Q587: How do constructors work in multi-level class hierarchies?
- Q591: How do function hierarchies compare to class hierarchies?
- Q598: Why doesn't EK9 have default parameter values?
- Q679: How do sealed classes with allow only work in EK9?