如何基于Java Record实现可扩展的不可变消息类?
解决方案
一、纯Java方案:用组合代替继承
Java的record是final类,无法被继承,因此可以用组合的方式复用已有record的逻辑,同时扩展新字段,全程保持不可变性。
示例代码:
interface Message<T> { T getBody(); } record SenderAwareMessage<T>(T body, Sender sender) implements Message<T> { @Override public T getBody() { return body; } } // 通过组合复用SenderAwareMessage的逻辑,新增priority字段 record PriorityMessage<T>(SenderAwareMessage<T> baseMessage, int priority) implements Message<T> { @Override public T getBody() { return baseMessage.getBody(); } // 提供便捷方法,避免外部直接调用baseMessage.sender() public Sender sender() { return baseMessage.sender(); } }
这种方式既保留了record的不可变特性,又实现了对基础消息类的扩展,逻辑清晰且符合Java设计规范。
二、接口扩展特性:实现多接口
通过定义不同功能的特性接口,让record实现多个接口,以此来“扩展”功能边界,避开record无法继承的限制。
示例代码:
interface Message<T> { T getBody(); } interface SenderAware { Sender getSender(); } interface PriorityAware { int getPriority(); } // 基础消息实现消息+ Sender感知接口 record SenderAwareMessage<T>(T body, Sender sender) implements Message<T>, SenderAware { @Override public T getBody() { return body; } @Override public Sender getSender() { return sender; } } // 带优先级的消息实现所有接口,扩展优先级特性 record PriorityMessage<T>(T body, Sender sender, int priority) implements Message<T>, SenderAware, PriorityAware { @Override public T getBody() { return body; } @Override public Sender getSender() { return sender; } @Override public int getPriority() { return priority; } }
该方式通过接口统一了对外的访问契约,每个record保持独立不可变,适合字段数量不多的场景。
三、第三方库:Lombok @Value(轻量替代)
如果觉得纯Java方案略显繁琐,可以使用Lombok的@Value注解——它会自动生成不可变类(final类、所有字段final、无setter),且支持继承,比Immutables更轻量化。
示例代码:
interface Message<T> { T getBody(); } @Value class SenderAwareMessage<T> implements Message<T> { T body; Sender sender; @Override public T getBody() { return body; } } // 直接继承SenderAwareMessage,扩展优先级字段 @Value class PriorityMessage<T> extends SenderAwareMessage<T> { int priority; // Lombok自动生成包含父类字段的构造器 public PriorityMessage(T body, Sender sender, int priority) { super(body, sender); this.priority = priority; } }
@Value生成的类天然具备不可变性,同时支持继承扩展,配置和使用都非常简洁。
内容的提问来源于stack exchange,提问作者ahrooran
相关产品推荐
相关产品推荐

