为不可变类实现clone()

时间:2012-11-03 09:36:43

标签: java clone class-design immutability

我正在开发一个类库。

  1. 我有一个矩阵的抽象基类Matrix,它提供了一些基本方法的实现。
  2. 派生自Matrix是不同类型矩阵的具体子类。
  3. 我要求矩阵可以克隆,因此Matrix实现了Cloneable接口。
  4. 从Matrix派生的一些类是不可变的
  5. 不可变类的克隆方法是否可以接受而不是返回对象的克隆,而是返回对象本身?

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

    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;
        }
        ...
    }
    

5 个答案:

答案 0 :(得分:10)

我原本以为调用super.clone()就足够了。

如果你的类是不可变的,那么在构造它时它应该已经克隆了任何可变类。因此,我认为你的班级有任何领域的浅拷贝是安全的。

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

答案 1 :(得分:4)

只需在不可变类的clone()实现中返回this

答案 2 :(得分:2)

虽然你可以让不可变类只是实现clone来返回对自己的引用,但我真的没有看到使用clone对可能或可能不可变的事情有多大价值,没有一些制作可变事物的可变对应方式,反之亦然。

我认为您的基础Matrix类最好包含方法IsImmutableIsWritable,以及AsImmutableAsMutable和{ {1}}方法;它还应包括读取和写入矩阵的方法(尽管在不可写矩阵上调用“write”方法应该抛出异常)。

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

可变类应该实现Matrix以将自己传递给AsImmutableCreateImmutableMatrix以返回自己,并AsMutable将自己传递给AsNewMutable

不可变类应该实现CreateMutableMatrix返回自己,AsImmutable来调用AsMutableAsNewMutable将自己传递给AsNewMutable

只读包装器应该实现CreateMutableMatrix来调用包装对象上的AsImmutable,并AsImmutableAsMutable来调用包装对象上的AsNewMutable

接收可能需要或可能不需要复制或变异的矩阵的对象可以简单地将其存储在字段中(例如AsNewMutable)。如果需要改变矩阵,它可以用Foo替换Foo。如果需要复制包含矩阵的对象,则应在副本中使用Foo.AsMutable()Foo.AsImmutable()替换该字段,具体取决于副本中的字段是否可能需要进行变异。

答案 3 :(得分:0)

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

如果有人想要继承ImmutableMatrix,如果您只是返回clone(),则无法通过调用super.clone()来实施this。因此,在这种情况下,您应该致电super.clone()

但是,如果您让自己的课程成为最终成绩,我认为没有理由不返回this

答案 4 :(得分:-1)

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

相关问题