我正在开发一个类库。
不可变类的克隆方法是否可以接受而不是返回对象的克隆,而是返回对象本身?
一些(过于简化的)代码澄清:
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;
}
...
}
答案 0 :(得分:10)
我原本以为调用super.clone()
就足够了。
如果你的类是不可变的,那么在构造它时它应该已经克隆了任何可变类。因此,我认为你的班级有任何领域的浅拷贝是安全的。
JavaDocs声明x.clone() != x
是首选。虽然这不是绝对的要求,但您的计划肯定会违反this
。
答案 1 :(得分:4)
只需在不可变类的clone()实现中返回this
。
答案 2 :(得分:2)
虽然你可以让不可变类只是实现clone
来返回对自己的引用,但我真的没有看到使用clone
对可能或可能不可变的事情有多大价值,没有一些制作可变事物的可变对应方式,反之亦然。
我认为您的基础Matrix
类最好包含方法IsImmutable
和IsWritable
,以及AsImmutable
,AsMutable
和{ {1}}方法;它还应包括读取和写入矩阵的方法(尽管在不可写矩阵上调用“write”方法应该抛出异常)。
定义静态方法AsNewMutable
和CreateImmutableMatrix
,给定CreateMutableMatrix
,将创建一个新的不可变或可变矩阵,并使用适当的数据进行预初始化。
可变类应该实现Matrix
以将自己传递给AsImmutable
,CreateImmutableMatrix
以返回自己,并AsMutable
将自己传递给AsNewMutable
。
不可变类应该实现CreateMutableMatrix
返回自己,AsImmutable
来调用AsMutable
,AsNewMutable
将自己传递给AsNewMutable
。
只读包装器应该实现CreateMutableMatrix
来调用包装对象上的AsImmutable
,并AsImmutable
和AsMutable
来调用包装对象上的AsNewMutable
。
接收可能需要或可能不需要复制或变异的矩阵的对象可以简单地将其存储在字段中(例如AsNewMutable
)。如果需要改变矩阵,它可以用Foo
替换Foo
。如果需要复制包含矩阵的对象,则应在副本中使用Foo.AsMutable()
或Foo.AsImmutable()
替换该字段,具体取决于副本中的字段是否可能需要进行变异。
答案 3 :(得分:0)
你的类不是严格不可变的,因为它不是最终的:可以有可变的子类。
如果有人想要继承ImmutableMatrix
,如果您只是返回clone()
,则无法通过调用super.clone()
来实施this
。因此,在这种情况下,您应该致电super.clone()
。
但是,如果您让自己的课程成为最终成绩,我认为没有理由不返回this
。
答案 4 :(得分:-1)
是如果我们看到String(不可变类)的行为,如果内容相同则返回相同的对象,所以我认为你是对的,clone()方法应该只返回它。