Why must this() or super() be the first statement in a constructor?

← Constructor Delegation · Ref: Q582

In EK9, this() or super() must be the very first statement in a constructor body. Any code before the delegation call produces error E05050.

THE RULE

Delegation calls (this() or super()) must be the first executable statement. No variable assignments, method calls, or assertions can come before them.

THE ERROR: E05050

E05050 fires when code appears before this() or super(). The compiler requires delegation to happen before any other logic.

WHY FIRST STATEMENT

Object initialization order must be predictable. The parent (or delegated constructor) sets up fundamental state. Child code runs after the base is established. This prevents accessing uninitialized parent state.

CORRECT PATTERN

Put all validation and logic AFTER the delegation:

  Child()
    -> value as Integer
    super(value)       // First statement
    assert value > 0   // Validation after

PARAMETER VALIDATION

If you need to validate parameters before construction, use a factory function or validate in the delegated constructor itself.

See Q580 for this() delegation. See Q581 for super() delegation. See Q583 for this() vs super() restrictions.

Example

defines module qa.constructor.delegationorder

  defines class

    Base as open
      label <- String()

      Base()
        -> label as String
        this.label: label

      label() as pure
        <- rtn as String: label

      default operator ?

    //Correct: super() is the first statement
    Derived extends Base
      priority <- 0

      Derived()
        ->
          label as String
          priority as Integer
        super(label)
        this.priority: priority

      //Another constructor: this() is the first statement
      Derived()
        -> label as String
        this(label, 1)

      priority() as pure
        <- rtn as Integer: priority

      default operator ?

  defines program

    DelegationOrderDemo()
      stdout <- Stdout()

      item1 <- Derived("alpha", 5)
      stdout.println(`${item1.label()}: priority ${item1.priority()}`)

      item2 <- Derived("beta")
      stdout.println(`${item2.label()}: priority ${item2.priority()}`)

Common mistakes

E05050 — The super() call must be the very first statement. Assigning fields before calling super() means the parent is not yet initialized, which is invalid. See ek9 -h E05050 for details.

Incorrect:

Derived()
        ->
          label as String
          priority as Integer
        this.priority: priority
        super(label)

Correct:

Derived()
        ->
          label as String
          priority as Integer
        super(label)
        this.priority: priority

E05050 — The this() delegation must be the first statement. No variable assignments or other code can precede it. See ek9 -h E05050 for details.

Incorrect:

Derived()
        -> label as String
        priority: 1
        this(label, 1)

Correct:

Derived()
        -> label as String
        this(label, 1)
Other ways to ask this
  • What is E05050 delegation not first statement?
  • Can I run code before this() or super()?
  • Why does my constructor delegation fail with E05050?

Coming from another language?

Java: this()/super() must be first statement (relaxed in Java 22). Python: super().__init__() can be anywhere. Kotlin: primary constructor handles this implicitly. C#: base()/this() must be in constructor header. EK9: E05050 enforces first-statement rule strictly.

Keywords: this, constant, super, first, statement, delegation, order, constructor, E05050