record 是什么?

record 是一种特殊的类,用于透明地建模不可变数据

基本语法

public record Point(int x, int y) {}

编译后自动生成:

  • 私有 final 字段private final int x, y;
  • 公共构造器public Point(int x, int y) { this.x = x; this.y = y; }
  • 公共访问器x() 和 y()(不是 getX()!)
  • equals() / hashCode():基于所有字段
  • toString():格式为 Point[x=1, y=2]
  • canEqual():确保类型安全比较

场景一:REST API 请求/响应 DTO

// 请求体
public record CreateUserRequest(String name, String email) {}// 响应体
public record UserResponse(Long id, String name, String email, LocalDateTime createdAt) {}@RestController
public class UserController {@PostMapping("/users")public ResponseEntity<UserResponse> createUser(@RequestBody CreateUserRequest request) {User user = userService.create(request.name(), request.email());UserResponse response = new UserResponse(user.getId(), user.getName(), user.getEmail(), user.getCreatedAt());return ResponseEntity.ok(response);}
}

代码量减少 80%,语义更清晰

场景二:数据库查询结果映射(Spring Data JPA)

// 自定义查询返回 record
public interface UserRepository extends JpaRepository<User, Long> {@Query("SELECT new com.example.dto.UserSummary(u.name, COUNT(o)) FROM User u LEFT JOIN u.orders o GROUP BY u")List<UserSummary> findUserOrderSummary();record UserSummary(String name, long orderCount) {}
}

无需额外 DTO 类,内联定义,类型安全

场景三:函数式编程中的数据载体

List<User> users = ...;// 使用 record 作为中间转换结果
List<UserStat> stats = users.stream().map(u -> new UserStat(u.getName(), u.getOrders().size())).filter(s -> s.orderCount() > 5).sorted(Comparator.comparing(UserStat::orderCount).reversed()).toList();// 定义
public record UserStat(String name, int orderCount) {}

完美契合 Stream API 的不可变数据流

场景四:JSON 序列化/反序列化(Jackson)

// record 默认支持 Jackson
public record Product(String name, BigDecimal price, List<String> tags) {}// JSON: {"name": "Phone", "price": 999.99, "tags": ["electronics", "mobile"]}
ObjectMapper mapper = new ObjectMapper();
Product product = mapper.readValue(json, Product.class);
String jsonOut = mapper.writeValueAsString(product);

Jackson 2.12+ 原生支持 record,无需额外注解