[英]Cloning objects in Java [3 questions]
will the clone method of Asub be called by doing this? 这样会调用Asub的clone方法吗? Or is Asub deep cloned properly?
还是正确克隆了Asub? If not, is there a way to propery deep clone Asub through this kind of method?
如果没有,是否有办法通过这种方法对Asub进行深度克隆?
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();
}
}
First of all, note that the clone() interface is broken , thus should not be used in new code. 首先,请注意clone()接口已损坏 ,因此不应在新代码中使用。 It is better to implement copy constructor(s) instead .
最好改为实现复制构造函数 。
However, if you really need to do it, the proper way is for TopMost
to implement Cloneable
. 但是,如果您确实需要这样做,则正确的方法是让
TopMost
实现Cloneable
。 Why? 为什么? Says Effective Java 2nd Edition, Item 11:
说有效的Java 2nd Edition,第11项:
So what does
Cloneable
do, given that it contains no methods?那么,鉴于
Cloneable
不包含任何方法,该怎么办? It determines the behavior ofObject
's protectedclone
implementation: if a class implementsCloneable
,Object
's clone method returns a field-by-field copy of the object;它确定
Object
的受保护clone
实现的行为:如果一个类实现Cloneable
,则Object
的clone方法返回该对象的逐字段副本; otherwise it throwsCloneNotSupportedException
.This is a highly atypical use of interfaces and not one to be emulated.否则会抛出
CloneNotSupportedException
。这是一种非常不典型的接口用法,而不是要模拟的接口。 Normally, implementing an interface says something about what a class can do for its clients.通常,实现接口会说明类可以为其客户端执行的操作。 In the case of
Cloneable
, it modifies the behavior of a protected method on a superclass.在
Cloneable
的情况下,它会修改超类上受保护方法的行为。
Moreover, Asub.clone
should be declared public
, not protected
- otherwise you can't call it from the outside world. 此外,应该将
Asub.clone
声明为public
,而不是protected
-否则您将无法从外部调用它。 Also, if you are using Java5 or above, it is legal and desirable for Asub.clone
to return Asub
, not Object
(and similarly for its superclasses). 另外,如果您使用的是Java5或更高版本,则
Asub.clone
返回Asub
而不是Object
(以及其超类类似)也是合法且合乎需要的。
You don't show any members in the classes - the implementations of clone
in the various classes can be a whole lot different depending on the types of members in that class. 您没有在类中显示任何成员-各个类中
clone
的实现可能完全不同,具体取决于该类中成员的类型。 Namely, if a class has any mutable members, you need to carefully deep copy all of them, otherwise you end up with distinct objects sharing their internal state. 即,如果一个类具有任何可变成员,则需要仔细地深度复制所有成员,否则最终将得到共享其内部状态的不同对象。
However, supposing your classes have only primitive or immutable fields, the cloning works as expected, although you have a lot of unnecessary clone
methods in your abstract classes, all of which simply call super.clone()
- you may be better off with Asub.clone()
only. 但是,假设您的类仅具有原始或不可变字段,尽管您的抽象类中有很多不必要的
clone
方法,所有这些clone
方法都只需调用super.clone()
即可进行克隆,所以克隆可以按预期工作-使用Asub.clone()
可能会更好Asub.clone()
仅。
As a side note, if Top a = (Top) super.clone()
is not a typo, you introduce a dependency from base class to derived class, which is not a good idea. 附带说明一下,如果
Top a = (Top) super.clone()
不是拼写错误,那么您将引入从基类到派生类的依赖关系,这不是一个好主意。
By allowing all abstract
subclasses implementing super.clone()
essentially does nothing (since all your abstract classes in your example are doing nothing) and just call (at the end) Object.clone()
method. 通过允许所有
abstract
子类实现super.clone()
本质上什么都不做(因为示例中的所有抽象类什么都不做),而只需调用(最后) Object.clone()
方法。
My suggestion is to allow all concrete classes (like ASub) to override the clone method and use the copy constructor idiom to create an exact clone of itself.... 我的建议是允许所有具体的类(如ASub)重写clone方法,并使用复制构造函数惯用法来创建其自身的精确克隆。
eg 例如
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);
}
}
PS Make TopMost
Cloneable PS使
TopMost
克隆
对super.clone()
的调用将禁用虚拟机制,因此仅调用Object.clone()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.