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()方法适合您,请使用它。但是,使用自定义接口可以利用泛型。