Convert JSON to a Java record (Java 16+)
Emit an immutable Java record from JSON. Records are concise, auto-generate equals/hashCode/toString, and are perfect for DTOs in Java 16 and later.
Detailed Explanation
Records: Immutable Data Carriers
Java 16 introduced record as a first-class language construct for data carrier classes. A record declares its components in a single line, and the compiler synthesizes accessors, equals(), hashCode(), and toString() automatically.
Example JSON
{
"id": 1,
"username": "alice",
"email": "alice@example.com"
}
Generated Java Record
package com.example.model;
public record User(Integer id, String username, String email) {}
Accessors
Records use the field name directly as an accessor (no get prefix):
User user = new User(1, "alice", "alice@example.com");
System.out.println(user.username()); // "alice"
When Records Beat Classes
- DTOs: data transfer between layers
- API responses: immutable, never mutated after deserialization
- Pattern matching (Java 21+): records destructure cleanly in switch expressions
- Map / Set keys: free
equalsandhashCodemake records natural composite keys
When Records Fall Short
- You need mutable fields → records are immutable by design
- You need inheritance → records implicitly extend
java.lang.Recordand cannot extend other classes - You need custom setters with validation → records validate via the canonical or compact constructor only
- You target Java 8 / 11 / 14 / 15 → records require Java 16
Custom Constructors
You can validate inputs in the compact constructor without restating the parameter list:
public record User(Integer id, String username, String email) {
public User {
Objects.requireNonNull(id, "id");
if (username.isBlank()) throw new IllegalArgumentException("username");
}
}
Records and Frameworks
Spring Boot 3+, Jackson 2.12+, and Hibernate 6+ all deserialize directly into records without configuration. Older versions may require additional modules (e.g., jackson-module-parameter-names).
Use Case
Modern Spring Boot 3 services targeting Java 17 LTS or newer can replace dozens of Lombok-annotated DTO classes with records, removing the Lombok dependency altogether and reducing build complexity.