记录类、类与 Lombok 的比较
比较记录类、传统类和 Lombok 注解,以选择合适的工具
记录类、类与 Lombok 的比较 是 CoddyKit 上的免费 Java Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。
记录类、类与 Lombok 的对比
Java 提供了多种创建数据载体类型的方式:包含样板代码的普通类、记录类(Java 16+)或 Lombok 注解。正确的选择取决于具体使用场景。
样板代码问题
一个用于简单数据载体的普通 Java 类需要大量样板代码:构造函数、获取方法、equals、hashCode 和 toString——仅仅为了几个字段就要编写这么多内容。
// Traditional class — lots of boilerplate
class ProductOld {
private final String id;
private final String name;
private final double price;
public ProductOld(String id, String name, double price) {
this.id = id; this.name = name; this.price = price;
}
public String getId() { return id; }
public String getName() { return name; }
public double getPrice() { return price; }
@Override public boolean equals(Object o) { /* ... */ }
@Override public int hashCode() { /* ... */ }
@Override public String toString() { /* ... */ }
}记录类解决方案
记录类可以将同样的类压缩为一行。编译器会自动生成所有样板代码。
// Record — one line, same functionality
record Product(String id, String name, double price) {}
// Usage is almost identical except accessors use component names (no get prefix)
Product p = new Product("P001", "Laptop", 999.99);
System.out.println(p.id()); // P001 (not getId())
System.out.println(p.name()); // Laptop
System.out.println(p.price()); // 999.99
System.out.println(p); // Product[id=P001, name=Laptop, price=999.99]Lombok @Data 与 @Value
Lombok 通过注解在编译时生成样板代码。@Value 会创建类似记录类的不可变类;@Data 会创建可变类。
// Lombok @Value — immutable (closest to record)
import lombok.Value;
@Value
public class LombokProduct {
String id;
String name;
double price;
// Lombok generates: all-args constructor, getters, equals, hashCode, toString
// Note: accessors follow getX() naming convention (getPrice(), not price())
}
// Lombok @Data — mutable
import lombok.Data;
@Data
public class MutableProduct {
private String id;
private String name;
private double price;
// Generates: getters, setters, equals, hashCode, toString, no-args constructor
}关键区别
记录类、Lombok @Value 和普通类之间的重要区别:
- 访问器命名:记录类使用
name();Lombok 使用getName() - 可变变体:记录类始终不可变;Lombok 通过 @Data 提供可变性
- 继承:记录类不能继承类;Lombok 类可以继承
- 构建工具依赖:Lombok 需要配置注解处理器;记录类是内置功能
何时使用记录类
在以下情况下,记录类非常适合:
- 类型主要是透明的数据载体(数据传输对象、值对象)
- 根据设计需要不可变性
- 使用 Java 16 或更高版本,并且希望零依赖
- 类型参与模式匹配(密封类 + 记录类)
// Perfect record use cases:
record Coordinates(double lat, double lon) {}
record JwtClaims(String subject, String role, long expiresAt) {}
record PageRequest(int page, int size, String sortBy) {}
record ErrorResponse(int code, String message, String path) {}
// These are all simple data carriers with no mutable state何时使用 Lombok
在以下情况下,优先考虑 Lombok:
- 需要可变 JavaBean(例如 JPA 实体、Spring 配置类)
- 访问器命名必须遵循 JavaBeans 约定(
getX),以便与框架兼容 - 需要使用
@Builder构建复杂对象 - 需要部分可变性(在某些字段上使用
@NonFinal)
// Lombok @Builder — great for complex object construction
import lombok.*;
@Builder
@Value
public class EmailMessage {
String to;
String from;
String subject;
String body;
List<String> attachments;
}
EmailMessage msg = EmailMessage.builder()
.to("user@example.com")
.from("noreply@app.com")
.subject("Welcome!")
.body("Thank you for signing up")
.attachments(List.of())
.build();何时使用普通类
在以下情况下,普通类仍然合适:
- 类包含超出简单数据承载范围的复杂行为
- 需要继承其他类
- 需要对 hashCode/equals 进行细粒度控制
- 需要带封装的可变状态
// Plain class — when behavior dominates over data
class ShoppingCart {
private final List<CartItem> items = new ArrayList<>();
private final String customerId;
public ShoppingCart(String customerId) {
this.customerId = customerId;
}
public void addItem(CartItem item) { items.add(item); }
public void removeItem(String sku) { items.removeIf(i -> i.sku().equals(sku)); }
public double total() { return items.stream().mapToDouble(CartItem::lineTotal).sum(); }
public boolean isEmpty() { return items.isEmpty(); }
}混合使用记录类和普通类
记录类和普通类可以无缝协作。在管理可变状态的类中,使用记录类保存不可变数据。
// Record for the immutable event data
record UserEvent(String userId, String action, java.time.Instant timestamp) {
public static UserEvent now(String userId, String action) {
return new UserEvent(userId, action, java.time.Instant.now());
}
}
// Class for the mutable event store
class EventLog {
private final List<UserEvent> events = new ArrayList<>();
public void record(String userId, String action) {
events.add(UserEvent.now(userId, action));
}
public List<UserEvent> eventsFor(String userId) {
return events.stream()
.filter(e -> e.userId().equals(userId)).toList();
}
}Spring Boot 中的记录类
记录类可以很好地与 Spring Boot 集成,用作请求/响应正文。Spring Boot 的 Jackson 映射器只需极少配置即可处理记录类。
// Spring Boot REST controller using records
import org.springframework.web.bind.annotation.*;
record CreateProductRequest(String name, double price, String category) {}
record ProductResponse(long id, String name, double price, String category) {}
@RestController
@RequestMapping("/api/products")
class ProductController {
@PostMapping
public ProductResponse create(@RequestBody CreateProductRequest req) {
// Jackson automatically deserializes JSON into the record
long id = productService.save(req);
return new ProductResponse(id, req.name(), req.price(), req.category());
}
}性能比较
对于简单的数据载体,三种方式生成的字节码基本相同。性能也完全一致——选择哪种方式取决于开发体验和需求。
// All three compile to approximately equivalent bytecode:
// - Records: compiler-generated, always immutable
// - Lombok @Value: annotation-processor-generated, always immutable
// - Plain class: hand-written
// The key runtime difference:
// Records: accessor is a method matching field name (price() not getPrice())
// Lombok/Class: accessor follows JavaBeans (getPrice())
// Jackson compatibility:
// Records: work natively in Jackson 2.12+ with no config
// Lombok: work with @JsonProperty or jackson-databind-lombok module快速检查
记录类的访问器遵循什么命名约定?
回顾:记录类、普通类与 Lombok
关键要点:
- 记录类会自动生成构造器、访问器(没有 get 前缀)、equals、hashCode 和 toString
- 记录类始终不可变;对于可变状态,请使用普通类
- Lombok @Value 可以近似实现记录类,但使用 getX() 命名并且需要配置
- Lombok @Builder 擅长构建包含许多可选字段的复杂对象
- 记录类非常适合数据传输对象、值对象以及应用程序接口请求/响应正文
- 当行为占主导地位或需要继承时,普通类仍然是最佳选择
用 AI 导师学习 Java — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 104
- 课程
- 374
常见问题解答
「记录类、类与 Lombok 的比较」课时是免费的吗?
是的 — 「记录类、类与 Lombok 的比较」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。
「记录类、类与 Lombok 的比较」这节课中我会学到什么?
比较记录类、传统类和 Lombok 注解,以选择合适的工具 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Java Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「记录类、类与 Lombok 的比较」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Java Academy 课中编写并运行代码吗?
能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 认识记录类
- 紧凑构造方法与验证
- 为记录类添加自定义方法
- 记录类、类与 Lombok 的比较