Java clone()方法是实现多态克隆的唯一方法吗?

Java clone()方法是实现多态克隆的唯一方法吗?,java,clone,deep-copy,cloneable,Java,Clone,Deep Copy,Cloneable,我需要为我的类配备多态性克隆(深度复制),也就是说,我需要这样的东西来工作: SuperType original = new SubType(); SuperType copy = original.clone(); 其中,original.clone()可以被任何机制替换以创建深度副本,copy的实际类型应为子类型,因为original也是子类型 clone()方法和Cloneable接口是实现这一点的唯一方法吗?工厂方法和复制构造函数不能被使用,因为实际的类只有在运行时才知道,对吗?除了

我需要为我的类配备多态性克隆(深度复制),也就是说,我需要这样的东西来工作:

SuperType original = new SubType();
SuperType copy = original.clone();
其中,
original.clone()
可以被任何机制替换以创建深度副本,
copy
的实际类型应为
子类型
,因为
original
也是
子类型

clone()
方法和
Cloneable
接口是实现这一点的唯一方法吗?工厂方法和复制构造函数不能被使用,因为实际的类只有在运行时才知道,对吗?除了那些序列化-反序列化方法之外,还有其他建议的方法吗?哪个方法比
clone()
方法更糟糕


谢谢,Petr

您可以简单地向SuperType添加一个复制方法,并在所有子类型中实现它

class SuperType {

    public SuperType copy() {
              ...
    }
}

如果您不喜欢
Cloneable
界面,您可以创建自己的界面。每个类都将负责创建正确类型的新实例。

实际上,对象的
克隆()
方法不允许您执行任何多态调用,因为它受
保护。实现
Cloneable
也没有用,因为它不包含
clone()
方法

您可以通过为克隆的类提供多态方法来执行多态性克隆,这些类反过来调用复制构造函数

abstract class SuperType {
    public SuperType(SuperType t) {
    }

    public abstract SuperType deepCopy();
}

class SomeType extends SuperType {

    SomeType(SomeType t) {
        //copy constructor
    }

    @Override
    public SomeType deepCopy() {                        
        return new SomeType(this);
    }
}

 ...

SuperType original = new SubType();
SuperType copy = original.deepCopy(); //the deepCopy is called on children classes
另见:


为了让代码正常工作,该代码要么在
超类型
类或子类中,要么你的
超类型
类型必须有一个公共的
clone()
方法。公共
clone()
方法不会自动存在,您必须实现它。在这个问题上,您可以将其称为任何其他名称,例如
copy()

那么,您的问题是如何实现
clone()
(或您所称的任何方法)方法,以便进行多态性克隆

Java开发人员打算采用的方法是调用
super.clone()
,假设继承层次结构中的所有类都以类似方式实现了
clone()
,以执行多态性克隆。这最终会得到受保护的
Object.clone()
方法,它实现了多态克隆的魔力。请注意,要使
Object.clone()
不引发异常,类必须实现
Cloneable
接口

然而,还有其他可能的方法。例如,假设所有子类都有一个默认构造函数,您可以执行类似于
this.getClass().newInstance()
的操作。这将创建正确类的对象,但不会复制字段。克隆方法将需要复制所有字段,子类必须重写克隆方法以复制其字段等。请注意,在这种情况下是否实现了
Cloneable
接口并不重要


另一种方法是,假设该类是可序列化的,则序列化并取消序列化
。这将创建一个多态克隆,其中包含所有可序列化字段。

您不能创建一个构造函数,将要克隆的对象传递给它?@gangqinlaohu当然可以,但是我需要调用
新的子类型(原始)
我不能,因为在编写代码时,我不知道原始代码是否属于类
子类型
,或
子类型2
,或
子类型
。好的,那就行了。但这与使用
clone()
有什么不同呢?
deepCopy()?您在
deepCopy()
中所做的事情不能在
clone()
中完成吗?@Posa克隆是一种java“内置”方式,无需复制构造函数即可提供对象副本。它试图让程序员的生活更轻松,但事实并非如此。是的,如果您在重写
clone()
时非常小心(Joshua Block的Effectiva Java有一整章关于它),您应该会得到相同的结果。这并不是因为我不喜欢
Clonable
。我不理解Don use clone panic(尽管我读过J.Bloch的书,但可能我不太理解与
clone
相关的发布)。为什么我要设计自己的界面,其目的基本上与
Clonable
相同?或者我自己的接口的用途会与可克隆的不同吗?好吧,你的问题是“克隆()方法和可克隆接口是实现这一点的唯一途径吗?”。如果clone()方法适合您,请使用它。但是,使用自定义接口可以利用泛型。