Record

  • https://docs.oracle.com/en/java/javase/17/language/records.html
  • Introduced in java 14
  • create immutable data class
  • immutability ensures validity of data without synchronization
  • It is implicitly final class
  • It extends the java.lang.Record abstract class imlpicitly
  • It automatically creates:
    • private, final fields
    • public constructor
    • equals(), hashCode() and toString() methods
    • public accessor methods with same name as fields
  • The following creates a Person record
    • name() and address() accessor methods
public record Person (String name, String address) {}
  • You can optionally have static field, static initializer or static method
  • Instance fields or instance initializers are not allowed
  • You can have nested classes/interfaces/records
  • You can have local records inside methods

Declaring canonical constructor

record Rectangle(double length, double width) {
    public Rectangle(double length, double width) {
        if (length <= 0 || width <= 0) {
            throw new java.lang.IllegalArgumentException(
                String.format("Invalid dimensions: %f, %f", length, width));
        }
        this.length = length;
        this.width = width;
    }
}
 
record Rectangle(double length, double width) {
    // compact constructor syntax
    public Rectangle {
        if (length <= 0 || width <= 0) {
            throw new java.lang.IllegalArgumentException(
                String.format("Invalid dimensions: %f, %f", length, width));
        }
    }
}

Declaring accessor methods

record Rectangle(double length, double width) {
 
    // Public accessor method
    public double length() {
        System.out.println("Length is " + length);
        return length;
    }
}

sealed classes/interfaces

  • works well with sealed classes and interfaces since records are implicitly final in nature
sealed interface Expr permits ConstantExpr {
    public int eval();
}
 
record ConstantExpr(int i) implements Expr {
    public int eval() { return i(); }
}