Record Classes (Java 16+) & Immutable Data Transfer Objects
1Concept
Records provide concise, boilerplate-free immutable data carrier classes. The compiler automatically generates `final` fields, canonical constructor, accessors, `equals()`, `hashCode()`, and `toString()`. Records support Compact Constructors for input validation.
2Architecture Diagram
record UserDto(String id, String email) {}
|
v javac generates automatically:
- final fields (id, email)
- canonical constructor
- accessors id(), email()
- equals(), hashCode(), toString()3Code Example
Core Java
public class RecordMasteryDemo {
public record Transaction(String txId, double amount, String currency) {
// Compact Constructor: clean validation without field assignment boilerplate
public Transaction {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
if (currency == null || currency.isBlank()) {
currency = "USD";
}
}
}
public static void main(String[] args) {
Transaction tx = new Transaction("TX-98214", 349.50, "USD");
System.out.println("Record instance: " + tx);
System.out.println("Accessor txId(): " + tx.txId());
System.out.println("Accessor amount(): $" + tx.amount());
}
}4Expected Output
Record instance: Transaction[txId=TX-98214, amount=349.5, currency=USD] Accessor txId(): TX-98214 Accessor amount(): $349.5
5Key Takeaways
- ✓Records cannot extend other classes (they implicitly extend `java.lang.Record`), but can implement interfaces.
- ✓Record components are shallowly immutable; if a record holds a mutable List, list elements can still change.
- ✓Use compact constructors for input validation and normalization.