可以将记录设为可克隆吗?

Is it okay to make a record cloneable?

我在 Google 上找不到任何关于 Cloneable records 的使用的 material。

我在想这样的事情:

record Foo() implements Cloneable {
    public Foo clone() {...}
}

这是好事吗?我们应该避免它以支持未来的枯萎吗?

除了fundamental problems of Cloneable还有一个不应该做记录的重要原因Cloneable:

记录本质上是不可变的。不可变 类 的最大优点之一是人们可以不再担心对象身份:任何两个具有相同值的对象都可以完全互换使用。 JavaDoc 有一个叫做 Value-based Classes 的概念,它更进一步(通过禁止 public 构造函数并使任何显式使用对象标识成为错误),但确实很好地描述了基本思想。

因此,创建一个 clone() 记录只会产生第二个对象,就所有意图和目的而言,该对象的行为应该与原始对象完全相同,并且不能'永远不会改变以表现不同(因为记录是不可变的)。

这表明没有正当理由 clone() Record

为了完整起见:可能(但同样不建议)在记录中实施Cloneable

record Foo(String a) implements Cloneable {
  public Foo clone() {
    try {
      return (Foo) super.clone();
    } catch (CloneNotSupportedException e) {
      throw new RuntimeException("this can't happen", e);
    }
  }
}

运行这段测试代码证明确实创建了一个克隆:

Foo original = new Foo("bar");
Foo clonedFoo = original.clone();
System.out.println(original + " / " + clonedFoo);
System.out.println(System.identityHashCode(original) + " / " + System.identityHashCode(clonedFoo));

产生这个输出:

Foo[a=bar] / Foo[a=bar]
670700378 / 1190654826