Java记录类(Record)深度解析:不可变数据建模与模式匹配实战

2025-07-12 0 486

Java记录类(Record)深度解析:不可变数据建模模式匹配实战

一、记录类核心特性

Java 16正式引入的透明数据载体:

// 基础记录类定义
public record Point(int x, int y) {
    // 紧凑构造器
    public Point {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("坐标不能为负数");
        }
    }
    
    // 添加派生方法
    public double distanceFromOrigin() {
        return Math.hypot(x, y);
    }
}

// 使用示例
Point p = new Point(3, 4);
System.out.println(p.x());      // 自动生成的访问器
System.out.println(p);          // 自动生成的toString()
Point copied = new Point(p.x(), p.y()); // 显式复制

核心优势:简洁语法不可变性自动实现模式匹配友好

二、高级应用模式

1. 嵌套记录结构

// 复杂领域模型建模
public record Order(
    String orderId,
    Customer customer,
    List items,
    LocalDateTime createdAt
) {
    // 静态工厂方法
    public static Order create(String orderId, Customer customer) {
        return new Order(orderId, customer, new ArrayList(), LocalDateTime.now());
    }
    
    // 业务逻辑方法
    public BigDecimal totalAmount() {
        return items.stream()
            .map(LineItem::subtotal)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

public record Customer(
    String customerId,
    String name,
    Address shippingAddress,
    Address billingAddress
) {}

public record LineItem(
    Product product,
    int quantity,
    BigDecimal unitPrice
) {
    public BigDecimal subtotal() {
        return unitPrice.multiply(new BigDecimal(quantity));
    }
}

2. 模式匹配应用

// instanceof模式匹配
public String processShape(Shape shape) {
    if (shape instanceof Circle c) {
        return String.format("圆形 半径=%.2f", c.radius());
    } else if (shape instanceof Rectangle r) {
        return String.format("矩形 宽=%.2f 高=%.2f", r.width(), r.height());
    }
    return "未知形状";
}

// switch表达式模式匹配(Java 21+)
public double calculateArea(Shape shape) {
    return switch (shape) {
        case Circle c -> Math.PI * c.radius() * c.radius();
        case Rectangle r -> r.width() * r.height();
        case Triangle t -> 0.5 * t.base() * t.height();
        default -> throw new IllegalArgumentException("不支持的形状");
    };
}

// 记录模式解构(Java 21+)
public void printCoordinates(Object obj) {
    if (obj instanceof Point(int x, int y)) {
        System.out.printf("坐标: (%d, %d)%n", x, y);
    }
}

三、序列化与持久化

1. JSON序列化方案

// Jackson配置
public class RecordModule extends SimpleModule {
    public RecordModule() {
        setMixInAnnotation(Point.class, PointMixin.class);
    }
    
    abstract static class PointMixin {
        @JsonCreator
        public PointMixin(@JsonProperty("x") int x, 
                         @JsonProperty("y") int y) {}
    }
}

// 使用示例
ObjectMapper mapper = new ObjectMapper()
    .registerModule(new RecordModule())
    .registerModule(new JavaTimeModule());

Point point = new Point(3, 4);
String json = mapper.writeValueAsString(point);
Point deserialized = mapper.readValue(json, Point.class);

2. JPA持久化策略

// JPA实体适配方案
@Entity
@Table(name = "orders")
public class OrderEntity {
    @Id
    private String orderId;
    
    @Embedded
    private Customer customer;
    
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List items = new ArrayList();
    
    // 转换为记录类
    public Order toRecord() {
        return new Order(
            orderId,
            customer.toRecord(),
            items.stream().map(LineItemEntity::toRecord).toList(),
            createdAt
        );
    }
    
    // 从记录类更新
    public void updateFromRecord(Order order) {
        this.items.clear();
        order.items().forEach(item -> 
            this.items.add(LineItemEntity.fromRecord(item)));
    }
}

// 使用示例
Order order = orderRepository.findById(id)
    .map(OrderEntity::toRecord)
    .orElseThrow();

四、领域驱动设计实战

1. 电商订单系统建模

// 核心领域模型
public record Order(
    OrderId id,
    CustomerId customerId,
    OrderStatus status,
    List items,
    Address shippingAddress,
    Money totalAmount,
    Instant createdTime
) {
    public enum OrderStatus { DRAFT, PAID, SHIPPED, COMPLETED, CANCELLED }
    
    // 领域行为
    public Order addItem(Product product, int quantity) {
        List newItems = new ArrayList(items);
        newItems.add(new OrderItem(
            product.id(),
            product.name(),
            product.price(),
            quantity
        ));
        return new Order(
            id, customerId, status, newItems, 
            shippingAddress, calculateTotal(newItems), createdTime
        );
    }
    
    public Order cancel() {
        if (status != OrderStatus.DRAFT) {
            throw new IllegalStateException("只能取消草稿订单");
        }
        return new Order(
            id, customerId, OrderStatus.CANCELLED, 
            items, shippingAddress, totalAmount, createdTime
        );
    }
}

// 值对象记录
public record Money(BigDecimal amount, Currency currency) {
    public Money add(Money other) {
        if (!currency.equals(other.currency)) {
            throw new IllegalArgumentException("币种不一致");
        }
        return new Money(amount.add(other.amount), currency);
    }
}

五、性能与兼容性指南

  • 内存占用:记录类比传统类节省20-30%内存
  • 反射限制:自动生成的字段为final且不可修改
  • 序列化:需要特殊处理构造函数逻辑
  • 模式匹配:Java 21+提供完整解构能力
  • 向后兼容:记录类可逐步替换传统DTO
Java记录类(Record)深度解析:不可变数据建模与模式匹配实战
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 java Java记录类(Record)深度解析:不可变数据建模与模式匹配实战 https://www.taomawang.com/server/java/277.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务