Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A compact canonical constructor is a specialized constructor syntax exclusive to Java Records, declared without a parameter list. It allows developers to intercept the initialization process of a record to perform data validation or normalization without explicitly declaring the parameters or writing boilerplate field assignments. The concepts of a “state description,” “components,” and a “canonical constructor” are specific to Java Records (introduced in Java 14). A canonical constructor is one whose signature exactly matches the record’s state description. While the compiler automatically generates this constructor, the compact syntax provides a mechanism to inject logic into the generated implementation.

Syntax

The compact canonical constructor is declared using the record’s name without any parentheses.
public record RecordName(Type component1, Type component2) {
    
    // Compact Canonical Constructor
    public RecordName {
        // Logic executes here
        // Implicit assignment to fields happens automatically at the end of this block
    }
}

Technical Mechanics and Compiler Rules

  1. Implicit Parameters: Although declared without a parameter list, the constructor is not parameterless. The parameters are implicitly declared to match the record’s components exactly in name, type, and order. They are directly accessible as local variables within the constructor body.
  2. Implicit Field Assignment: You do not write this.component1 = component1;. The compiler automatically appends the assignment of the implicit parameters to the corresponding private final instance fields at the end of the constructor block.
  3. Parameter Mutation for Normalization: Because the implicit assignment happens at the end of the block, you can normalize data by reassigning the implicit parameter variables directly.
  4. Restriction on this: Explicitly assigning values to instance fields using this.component = value inside a compact constructor is a compilation error. The fields are strictly initialized by the compiler-generated assignments.
  5. Restriction on return Statements: A compact constructor cannot contain return statements. This is a strict compiler restriction and a major functional difference from explicit canonical constructors, where early returns are permitted.
  6. Access Modifiers: If the access modifier is omitted on a compact constructor, the compiler automatically applies the record’s access modifier. If explicitly declared, the modifier must provide at least as much access as the record class itself.

Code Example

The following example demonstrates the mechanics of implicit parameters, automatic assignment, and implicit access modifiers:
public record Dimensions(double length, double width) {
    
    // Access modifier is omitted; compiler automatically applies 'public'
    Dimensions {
        // 1. The parameters 'length' and 'width' are implicitly available.
        if (length < 0 || width < 0) {
            throw new IllegalArgumentException("Dimensions must be positive");
        }
        
        // 2. Mutating the implicit parameter normalizes the data 
        // before the compiler assigns it to the instance field.
        if (length == 0) {
            length = 1.0; 
        }
        
        // 3. No return statements are allowed here.
        
        // 4. The compiler automatically inserts:
        // this.length = length;
        // this.width = width;
    }
}

Contrast with Standard Canonical Constructor

To understand the abstraction, compare the compact syntax with the equivalent explicit canonical constructor declaration within a record. Both achieve the exact same bytecode result, but the compact version eliminates boilerplate. Explicit Canonical Constructor:
public record Dimensions(double length, double width) {
    public Dimensions(double length, double width) {
        if (length < 0 || width < 0) {
            throw new IllegalArgumentException();
        }
        this.length = length;
        this.width = width;
    }
}
Compact Canonical Constructor:
public record Dimensions(double length, double width) {
    public Dimensions {
        if (length < 0 || width < 0) {
            throw new IllegalArgumentException();
        }
        // Assignments are implicit
    }
}
Master Java with Deep Grasping Methodology!Learn More