JDK 16随时间推移的记录、构造函数和添加



我对使用新的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共享上的驱动器类型"远程"驱动器意外地被添加了

我发现自己试图想出一些方案,比如使用CCD_;远程";状态,但实际上这就是开发枚举的原因。

这种情况下我该怎么办?我可以向构造函数添加选项并将它们存储在私有的最终字段中吗?或者我应该使DrivePacket->RemoteDrivePacket,还是我应该为RemoteDrivePacket制作一个标记接口?

开发人员打算使用的典型方式是什么?

它们不能被子类化,也不能有"单独添加一个"意义上的字段,但你可以简单地在其中添加一个新属性;public record DrivePacket(Path drivePath, long driveSize, String id) {}运行良好。

当然,现在所有创建新DrivePacket对象的代码都需要更新。您应该能够添加一个自定义构造函数,例如填充一些默认值。

如果您希望它们是可构建的、可扩展的、具有非最终字段等,请查看lombok的@Value。(免责声明:我确实在lombok上工作(。

--编辑--

我想我应该在这里添加这个构造函数,以展示如何确保调用new DrivePacket(path, size)(无id(的"旧"代码能够工作:

public record DrivePacket(Path drivePath, long driveSize, String id) {
public DrivePacket(Path drivePath, long driveSize) {
this(drivePath, driveSize, "");
}
}

"完整"的全三元构造函数也存在,这定义了第二个构造函数,确保任何刚进入new DrivePacket(path, size)的代码都能获得""的ID。所有DrivePacket都有一个ID(你不能让它们中的一半有ID,另一半没有;然后"DrivePacket"将不再描述单一类型的概念,而不是java的工作方式(,现在老式的DrivePacket对象有一个空的ID字符串。

如果有合理的默认值,并且在设计该功能时考虑到了这一点,则可以将组件兼容地添加到记录中。考虑:

record Point(int x, int y) { }

并且您希望添加一个z组件,其中零是合理的默认值。如果你只是盲目地将其更改为

record Point(int x, int y, int z) { }

这与现有的客户端不兼容源代码或二进制代码,但您可以通过为旧的状态描述提供一个替代构造函数来解决这个问题:

record Point(int x, int y, int z) { 
public Point(int x, int y) { this(x, y, 0); }
}

现在,旧的构造函数调用(二进制和源代码(和旧的序列化实例(如果默认值与序列化将用于序列化流中不存在的字段的零默认值相同(将按预期工作。但是,它与重命名重新排序删除组件不兼容。

最新更新