【发布时间】:2021-06-04 01:23:02
【问题描述】:
我对使用新的 JDK 16 记录很感兴趣,但是当我尝试创建一个具有附加参数的新记录时,我收到一个错误:
public record DrivePacket(Path drivePath, long driveSize) {
public DrivePacket(Path drivePath, long driveSize) {
this.drivePath = drivePath;
this.driveSize = driveSize;
}
public DrivePacket(Path drivePath, long driveSize, String ID) {
this(drivePath, driveSize);
this.id = id;
}
}
是否只针对没有任何可变性的对象进行记录,或者它们可以随着时间的推移而扩展?
我对这种类型的类有一个新要求(特别是意外添加了通过 NFS 共享的驱动器类型“远程”驱动器。
我发现自己试图想出一些方案,比如使用driveSize 来表示“远程”状态,但这确实是开发枚举的原因。
在这种情况下我该怎么办?我可以向构造函数添加选项并将它们存储在私有最终字段中吗?或者我应该做一个DrivePacket的子类 -> RemoteDrivePacket,还是应该为RemoteDrivePacket做一个标记接口?
开发人员打算使用的典型方式是什么?
【问题讨论】:
-
docs.oracle.com/en/java/javase/16/language/records.html 您已将记录定义为具有两个属性(
drivePath和driveSize),您不能转而向其添加任意属性。记录类不能被子类化;它们隐含为final。它们可以扩展,但您尝试在错误的级别进行扩展。 -
记录是根据特定目的设计的。在您的情况下,如果您将记录定义为具有 ID 并且有一个 ctor 调用带有虚拟 ID(或其他)的规范 ctor,那么它就可以了。您也可以使用静态工厂,尽管这里似乎没有必要。我真的没有在这里看到故障点或设计疏忽。它们被明确设计为轻量级数据载体类。
-
如果您的应用程序需要类的更广泛的功能......例如子类化,以便您的设计的这方面可以在不重新编码的情况下发展......使用常规类。是的 - 您确实需要尽早做出正确的决定以预测未来的需求。但这适用于所有方面。
-
阅读JEP 395 了解有关记录的所有信息、发明的原因以及特征和限制。
-
我还要补充一点,即使使用常规类,也不会按照示例中显示的方式完成,其中任意成员属性(非常规命名的
ID)试图成为设置——您通常会添加成员属性,就像使用记录一样。