一个记录类自动获取许多标准成员:
- 对于头部中的每个组件,两个成员:一个与组件同名且返回类型相同的公共访问器方法,以及一个与组件类型相同的私有 final 字段;
如果生成的 final 字段与访问器方法具有相同的名称,为什么不生成公共 final 字段呢?
由于记录类的实例可以序列化和反序列化,因此记录组件几乎不会被小心地更改。但是,不能通过提供 writeObject、readObject、readObjectNoData、writeExternal 或 readExternal 方法来自定义流程
所以改变 API 内部实现(记录组件)不是一个合适的理由。但我从@Brian Goetz那里得到了充分的理由
谢谢大家关注我的傻问题
我认为这个决定的一个关键因素是你现在有能力覆盖Record 的 getter:
public record MyRecord(String myProperty) {
@Override
public String myProperty() {
return "The property is " + myProperty;
}
}
Run Code Online (Sandbox Code Playgroud)
对于公共最终字段来说,这样的事情是不可能的。
记录可以实现接口,因此记录的访问器可以是接口方法的实现。此外,使用访问器而不是直接字段访问提供了更大的灵活性,例如,您可以将直接返回字段的访问器替换为以某种方式派生值的访问器(反之亦然)。
记录还允许您覆盖访问器 - 而不是简单地返回字段 - 做一些额外的事情。使记录使用直接字段访问会限制和限制您可以对记录执行的操作,从而限制它们的有用性,而让访问器为您提供直接字段访问提供的基线,并在必要时能够执行更多操作。
引用Holger在评论中提供的示例:
类
public record R(int a, int b) { public int c() { return …; }}并public record R(int a, int c) { public int b() { return …; }}提供相同的 API,无论它们的内部表示如何。
简而言之,为字段生成访问器比直接字段访问提供了更多的灵活性和功能。这同样适用于普通的不可变类。
Brian Goetz在对此答案的评论中提供了另一个原因:
如果没有覆盖访问器的能力,记录将无法正确支持可变对象(例如数组)作为组件。如果您有一个数组组件,您可能希望在构造函数和访问器中执行防御性复制(这也需要覆盖 equals,以保留 Record 的规范);如果它是公共 final 字段,则无法封装组件的可变性
| 归档时间: |
|
| 查看次数: |
376 次 |
| 最近记录: |