如何隐藏提供静态工厂方法的Java Record构造方法?
如何隐藏Java Record的规范构造方法,强制通过静态工厂方法实例化?
Java Record的规范构造方法(Canonical Constructor)访问权限默认与Record本身一致,且不能设置为比Record更严格的权限(比如public的Record不能把规范构造改成private),这是Java语言规范的硬性要求。针对你想要让days自动计算、禁止外部传入的需求,可以采用以下两种方案:
方案一:用紧凑构造方法强制覆盖days的值
保留days作为Record组件,但通过紧凑构造方法忽略外部传入的days参数,强制用计算值替换:
import java.time.LocalDate; import java.time.temporal.ChronoUnit; public record DatePair(LocalDate start, LocalDate end, long days) { // 紧凑构造方法,访问权限与Record一致(public) public DatePair { // 忽略传入的days参数,强制计算正确的间隔天数 days = ChronoUnit.DAYS.between(start, end); } public static DatePair of(LocalDate start, LocalDate end) { // 此处传入的days值会被构造方法覆盖,可传任意占位值 return new DatePair(start, end, 0); } }
这种方式下,即使外部代码直接调用new DatePair(start, end, 999),最终的days值依然是计算出来的正确结果,相当于间接实现了“禁止外部指定days”的目的,同时保证了数据的一致性。
方案二:将days改为派生计算方法(更符合Record设计初衷)
Record的核心是承载原始不可变数据,派生属性不适合作为Record组件。可以把days从组件列表中移除,改成一个计算方法:
import java.time.LocalDate; import java.time.temporal.ChronoUnit; public record DatePair(LocalDate start, LocalDate end) { // 派生计算方法,替代原days组件 public long days() { return ChronoUnit.DAYS.between(start, end); } // 静态工厂方法可保留,也可省略(直接调用new DatePair(start, end)即可) public static DatePair of(LocalDate start, LocalDate end) { return new DatePair(start, end); } }
这种设计更简洁,完全避免了构造方法的权限问题——外部代码根本无法传入days参数,因为Record的规范构造方法只需要start和end,同时days()方法依然可以公开访问,满足你的需求。
内容的提问来源于stack exchange,提问作者Basil Bourque
相关产品推荐
相关产品推荐

