A flexible constructor body can perform permitted statements before its explicit superclass or delegated-constructor invocation while respecting early-construction restrictions.
Java 25 constructor validation before superclass initialization
Java 25+. The program uses JDK classes and requires no preview flags.
Reject before passing the value onward
A shipment quantity is required by the superclass constructor. Validate and convert the incoming quantity before invoking super, so the base object receives a checked value. The validation is about the input argument; it does not read partially initialized instance state.
Java 25 permits this prologue under specific construction rules. It is not permission to call arbitrary instance methods before the superclass exists. Local computations and input checks should remain separate from callbacks that expect the full object invariant. Publishing this from construction still needs its own review.
The example uses a long input and Math.toIntExact before the base constructor. That keeps both negative quantities and values too large for the base representation out of the initialized object. The failed construction creates no application registry entry because publication is not part of this constructor.
Keep delegating paths consistent
If the class has several constructors, make each path converge on the same validated invariant. Duplicated checks tend to drift when a new parameter is introduced. A constructor that accepts already validated data can be private, while the public boundary owns conversion and rejection.
Working program
public class CheckedShipmentConstruction {
static class Quantity { final int units;Quantity(int units){this.units=units;} }
static class Shipment extends Quantity {
Shipment(long requested){
if(requested<0)throw new IllegalArgumentException("Negative shipment");
int validated=Math.toIntExact(requested);
super(validated);
}
}
public static void main(String[] args){
System.out.println(new Shipment(9).units);
try{new Shipment(-1);}catch(IllegalArgumentException rejected){System.out.println("negative rejected");}
try{new Shipment(3_000_000_000L);}catch(ArithmeticException rejected){System.out.println("range rejected");}
}
}Output
9
negative rejected
range rejectedCosts and boundaries
Scalar validation and conversion take constant work. This language feature changes permitted constructor structure, not the arithmetic range or object-publication rules. The source requires Java 25 without preview flags; it is not a Java 8-compatible constructor.
Common Mistakes
- The prologue is not a fully initialized instance.
- A constructor failure does not undo unrelated external side effects.
- Do not claim a newer language feature compiles under an earlier release.
