用Java克隆对象[3个问题]
这样做会调用Asub的克隆方法吗?或者Asub深度克隆是否正确?如果没有,有没有办法通过这种方法实现Asub的深度克隆用Java克隆对象[3个问题],java,class,abstract-class,clone,Java,Class,Abstract Class,Clone,这样做会调用Asub的克隆方法吗?或者Asub深度克隆是否正确?如果没有,有没有办法通过这种方法实现Asub的深度克隆 abstract class Top extends TopMost { protected Object clone() { Object obj = super.clone(); // deep copy and try catch } } abstract class A extends Top { prot
abstract class Top extends TopMost {
protected Object clone() {
Object obj = super.clone();
// deep copy and try catch
}
}
abstract class A extends Top {
protected Object clone() {
Object obj = super.clone();
// deep copy and try catch
}
}
class Asub extends A {
protected Object clone() {
Object obj = super.clone();
// deep copy and try catch
}
public void doSomethingNew() {
}
}
abstract class TopMost {
public void someMethod() {
Top a = (Top) super.clone();
// more code here
}
}
public class Main {
public static void main(String... args) {
Asub class1 = new Asub();
class1.someMethod();
}
}
首先,请注意,,因此不应在新代码中使用。最好是实现复制构造函数 但是,如果确实需要这样做,正确的方法是让
TopMost
实现Cloneable
。为什么?有效Java第二版第11项:
既然Cloneable
不包含任何方法,那么它能做什么呢?它决定
对象
受保护的克隆
实现的行为:如果类实现
Cloneable
,Object
的clone方法返回对象的逐字段副本;
否则它会抛出CloneNotSupportedException
。这是一种非常非典型的用法
接口,而不是要仿真的接口。通常,实现一个接口
说明类可以为其客户机做些什么。在可克隆的情况下
,
它修改超类上受保护方法的行为
此外,Asub.clone
应该声明为public
,而不是protected
——否则您不能从外部世界调用它。另外,如果您使用的是Java5或更高版本,那么Asub.clone
返回Asub
,而不是对象(同样地,它的超类也是如此)是合法且可取的
类中没有显示任何成员-不同类中的clone
实现可能会有很大不同,具体取决于该类中的成员类型。也就是说,如果一个类有任何可变成员,则需要仔细地深度复制所有成员,否则最终会导致不同的对象共享其内部状态
但是,假设您的类只有基本字段或不可变字段,那么克隆工作与预期的一样,尽管您的抽象类中有许多不必要的clone
方法,所有这些方法都只需调用super.clone()
——您最好只使用Asub.clone()
作为旁注,如果Top a=(Top)super.clone()
不是一个打字错误,那么将从基类到派生类引入一个依赖项,这不是一个好主意。首先,请注意,因此不应在新代码中使用。最好是实现复制构造函数
但是,如果确实需要这样做,正确的方法是让TopMost
实现Cloneable
。为什么?有效Java第二版第11项:
既然Cloneable
不包含任何方法,那么它能做什么呢?它决定
对象
受保护的克隆
实现的行为:如果类实现
Cloneable
,Object
的clone方法返回对象的逐字段副本;
否则它会抛出CloneNotSupportedException
。这是一种非常非典型的用法
接口,而不是要仿真的接口。通常,实现一个接口
说明类可以为其客户机做些什么。在可克隆的情况下
,
它修改超类上受保护方法的行为
此外,Asub.clone
应该声明为public
,而不是protected
——否则您不能从外部世界调用它。另外,如果您使用的是Java5或更高版本,那么Asub.clone
返回Asub
,而不是对象(同样地,它的超类也是如此)是合法且可取的
类中没有显示任何成员-不同类中的clone
实现可能会有很大不同,具体取决于该类中的成员类型。也就是说,如果一个类有任何可变成员,则需要仔细地深度复制所有成员,否则最终会导致不同的对象共享其内部状态
但是,假设您的类只有基本字段或不可变字段,那么克隆工作与预期的一样,尽管您的抽象类中有许多不必要的clone
方法,所有这些方法都只需调用super.clone()
——您最好只使用Asub.clone()
作为旁注,如果Top a=(Top)super.clone()
不是一个打字错误,那么将从基类到派生类引入一个依赖项,这不是一个好主意。调用super.clone()
禁用虚拟机制,因此它只调用Object.clone()
调用super.clone())
禁用虚拟机制,因此它只调用Object.clone()
,方法是允许所有abstract
子类实现super.clone()
我的建议是允许所有具体类(如ASub)重写clone方法,并使用该习惯用法创建自身的精确克隆
e、 g
PS通过允许所有抽象子类实现super.clone()
基本上什么都不做(因为示例中的所有抽象类什么都不做),只需调用(最后)Object.clone()
方法,就可以使最顶层的可克隆
我的建议是允许所有具体类(如ASub)重写clone方法,并使用该习惯用法创建自身的精确克隆
e、 g
PSMaketop
Cloneable是和可能
不是因为Cloneable
只是一个标记接口。@不幸的是,精英绅士Cloneable
不仅仅是一个标记接口。请参阅我的更新。@Péter Török,s
public abstract class TopMost {
public TopMost(TopMost rhs) {
}
}
public abstract class Top extends TopMost {
public Top(Top rhs) {
super(rhs);
//whatever you need from rhs that only is visible from top
}
}
public abstract class A extends Top {
public A (A rhs) {
super(rhs);
//TODO: do rhs copy
}
}
public class ASub extends A {
public ASub(ASub rhs) {
super(rhs);
//TODO: copy other stuff here....
}
public Object clone() {
return new ASub(this);
}
}