How do I call one constructor from another using this()?
← Constructor Delegation · Ref: Q580
Use this() as the first statement in a constructor to delegate to another constructor of the same class. This avoids duplicating initialization logic.
BASIC DELEGATION
Call this() with arguments matching another constructor:
Account()
-> name as String
this(name, 0.0) //delegates to two-arg constructor
Account()
-> name as String, balance as Float
this.name: name
this.balance: balance
MUST BE FIRST STATEMENT
this() must be the very first statement in the constructor body. No code can execute before delegation (E05050).
CHAINING MULTIPLE
Constructors can chain through multiple levels:
Account() -> this("anonymous") -> this("anonymous", 0.0)
Each level delegates to a more specific constructor.
NO CIRCULAR DELEGATION
Constructor chains must terminate. A circular chain (A calls B calls A) is a compile error.
See Q581 for super() delegation. See Q582 for delegation order rules. See Q583 for this() vs super() restrictions. See Q94 for constructor basics. See Q605 for why 'this' is invalid in standalone functions.
Example
defines module qa.constructor.thisdelegation defines class Account holder <- String() balance <- 0.0 accountType <- String() //One-arg delegates to two-arg Account() -> holder as String this(holder, 0.0) //Two-arg delegates to three-arg Account() -> holder as String balance as Float this(holder, balance, "standard") //Three-arg: does the actual initialization Account() -> holder as String balance as Float accountType as String this.holder: holder this.balance: balance this.accountType: accountType holder() as pure <- rtn as String: holder balance() as pure <- rtn as Float: balance accountType() as pure <- rtn as String: accountType default operator ? defines program ThisDelegationDemo() stdout <- Stdout() //Uses one-arg constructor (delegates through chain) acc1 <- Account("Alice") stdout.println(`${acc1.holder()}: ${acc1.balance()} (${acc1.accountType()})`) //Uses two-arg constructor acc2 <- Account("Bob", 100.0) stdout.println(`${acc2.holder()}: ${acc2.balance()} (${acc2.accountType()})`) //Uses three-arg constructor directly acc3 <- Account("Charlie", 500.0, "premium") stdout.println(`${acc3.holder()}: ${acc3.balance()} (${acc3.accountType()})`)
Common mistakes
E05050 — The this() delegation call must be the very first statement in the constructor body. No field assignments or other code can appear before it. See ek9 -h E05050 for details.
Incorrect:
Account()
-> holder as String
this.holder: holder
this(holder, 0.0)
Correct:
Account()
-> holder as String
this(holder, 0.0)
Other ways to ask this
- How does constructor chaining work in EK9?
- How do I delegate between constructors with this()?
- What is this() in a constructor?
Coming from another language?
Java: this() constructor chaining, must be first statement. Python: no this() equivalent. Kotlin: primary constructor + this() delegation. C#: this() chaining, must be first. EK9: this() delegation with first-statement rule, E05050 if not first.
Keywords: this, constant, super, first, statement, delegation, constructor, chain, E05050