7

我正在开发一个类库。

  1. 我有一个用于矩阵的抽象基类 Matrix,它提供了一些基本方法的实现。
  2. 派生自 Matrix 的是不同类型矩阵的具体子类。
  3. 我要求矩阵是可克隆的,所以 Matrix 实现了 Cloneable 接口。
  4. 从 Matrix 派生的一些类是不可变的

不可变类的克隆方法是否可以接受,而不是返回对象的克隆,而是返回对象本身?

一些(过度简化的)代码用于澄清:

abstract class Matrix implements Cloneable {
   ...
}

class ImmutableMatrix extends Matrix {
    ImmutableMatrix clone() {
        return this;
    }
    ...
}

class SomeOtherMatrix extends Matrix {
    SomeOtherMatrix clone() {
        SomeOtherMatrix other = super.clone();
        ...
        return other;
    }
    ...
}
4

5 回答 5

11

我原以为打电话super.clone()就足够了。

如果您的类是不可变的,那么它应该在构造时已经克隆了任何可变类。因此,我认为拥有您班级拥有的任何字段的浅表副本是安全的。

x.clone() != x首选的 JavaDocs 状态。虽然这不是绝对要求,但您的计划肯定会违反 returnthis

于 2012-11-03T09:51:29.330 回答
4

只需返回this不可变类的 clone() 实现即可。

于 2012-11-09T16:04:33.607 回答
4

虽然您可以让不可变类简单地实现clone以返回对自身的引用,但我真的认为在clone可能或可能不可变的事物上使用没有太大价值,因为缺少某种使不可变事物的可变应对的方法,反之亦然。

我认为您的基Matrix类最好包含方法IsImmutableIsWritable以及AsImmutable,AsMutableAsNewMutable方法;它还应该包括读取和写入矩阵的方法(尽管在不可写矩阵上调用“write”方法应该会引发异常)。

定义静态方法CreateImmutableMatrixCreateMutableMatrix给定 a Matrix,将创建一个新的不可变或可变矩阵,该矩阵已使用适当的数据进行预初始化。

可变类应该实现AsImmutable将自己传递给CreateImmutableMatrixAsMutable返回自己,并将AsNewMutable自己传递给CreateMutableMatrix

不可变类应该实现AsImmutable返回自己、AsMutable调用AsNewMutable并将AsNewMutable自己传递给CreateMutableMatrix.

只读包装器应该实现AsImmutable调用AsImmutable被包装的对象,并AsMutable调用AsNewMutableAsNewMutable包装的对象。

接收可能需要或可能不需要复制或变异的矩阵的对象可以简单地将其存储在字段中(例如Foo)。如果它需要改变矩阵,它可以替换FooFoo.AsMutable(). 如果需要复制包含矩阵的对象,则应根据副本中的字段是否可能需要更改来替换副本中Foo.AsImmutable()Foo.AsNewMutable()字段。

于 2012-11-12T22:47:04.107 回答
1

您的类不是严格不可变的,因为它不是最终的:可以有可变的子类。

如果有人想子类化,如果你只是返回ImmutableMatrix,他将无法clone()通过调用来实现。因此,在这种情况下,您应该调用.super.clone()thissuper.clone()

但是,如果您将班级定为决赛,我看不出有什么理由不直接 return this

于 2013-07-12T08:59:25.257 回答
-1

是的,如果我们看到 String(不可变类)的行为,如果内容相同,则返回相同的对象,所以我认为你是对的,clone() 方法应该只返回这个。

于 2012-11-03T10:05:18.730 回答