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
,无需额外注解