Flexible Constructor Bodies
For 30 years, a Java constructor that called super(...) or this(...) had to make that call its very first statement. If you wanted to check an argument first, you couldn't; you had to squeeze the check into a helper method inside the call. Java 25 (JEP 513) relaxed that rule. A constructor can now run ordinary code before calling super(...) or this(...), as long as that code doesn't touch the object being built.
Validate Before Calling super
Here SavingsAccount requires a minimum balance. It checks the argument before asking the parent class to build its part:
public class Flex {
static class Account {
final String holder;
final long balance;
Account(String holder, long balance) {
this.holder = holder;
this.balance = balance;
}
}
static class SavingsAccount extends Account {
SavingsAccount(String holder, long balance) {
if (balance < 1000) {
throw new IllegalArgumentException("Need at least Rs. 1000");
}
super(holder.trim(), balance);
}
}
public static void main(String[] args) {
Account s = new SavingsAccount(" Navika ", 5000);
System.out.println("[" + s.holder + "] Rs. " + s.balance);
try {
new SavingsAccount("Advitha", 10);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
}[Navika] Rs. 5000
Need at least Rs. 1000How it works
SavingsAccount extends Accountmakes it a subclass (see "Inheritance in Java"). Its constructor must call the parent's constructor withsuper(...).- Lines 14 to 16 run before
super(...): an invalid balance is rejected before any part of the object is built. - Line 17 calls
super(...)with a cleaned-up name. On Java 24 and earlier, this constructor didn't compile.
Try it yourself: move the if block below the super(...) line. Does it still work? Which version rejects bad input earlier?
What the Prologue May and May Not Do
In the prologue (before super/this) | Allowed? |
|---|---|
| Check arguments, throw exceptions | Yes |
| Declare and compute local variables | Yes |
| Call static methods | Yes |
Assign this class's own fields (this.x = ...) | Yes |
Read fields, call instance methods, pass this anywhere | No |
The object isn't built yet, so reading it is unsafe. The compiler stops you:
FlexThis.java:1: error: cannot reference this before supertype constructor has been called
class A { int x; A() { System.out.println(this.x); super(); } }
^Why Assigning Fields Early Helps
A parent constructor sometimes calls a method that the subclass has overridden (see "Method Overriding in Java"). Before Java 25, that method could see the subclass's fields still at their default values, because the subclass hadn't set them yet. Now the subclass can assign its fields in the prologue, before super(...) runs, so even code called from the parent sees real values.
Common Mistakes
Using this in the prologue. Reading a field or calling an instance method before super(...) doesn't compile.
Expecting it on older Java. Statements before super(...) fail to compile on Java 24 and earlier (it was a preview feature in 22 to 24).
Calling super(...) twice or inside an if. A constructor still has exactly one super(...) or this(...) call, at the top level of its body.
Practice
- Easy: In the earlier
BankAccountchain from "Constructor Overloading and Constructor Chaining", add a check beforethis(holder, 0)that rejects an empty name. - Harder: Write a parent class
Shape(String name)and a subclassCircle(double radius)that rejects a negative radius before callingsuper("circle").
Key Takeaways
Was this tutorial helpful?