简体   繁体   English

是clone()会真正在对象内部克隆接口变量

[英]is clone() will really clone the interface variable inside an object

I have a class with clonable interface implemented 我有一个实现了可克隆接口的类

public class BaseModelItem extends WiSeConBaseModel implements Cloneable{
private ValueChangeObserver observer=null;

//setting interface other values here

    @Override
    public WiSeConBaseModelItem clone() {
        return (WiSeConBaseModelItem) super.clone();
    }
}

And the interface looks 界面看起来

public interface ValueChangeObserver {
onChanged(Object obj);
}

My question is I have five variables other than interface variable while cloning all five variables is getting but not this interface variable. 我的问题是我除了克隆接口变量之外还有五个变量而不是接口变量。

Is there any issue of cloning of an interface object or any other issue? 是否存在克隆接口对象的问题或任何其他问题?

Thanks in advance 提前致谢

My question is I have five variables other than interface variable while cloning all five variables is getting but not this interface variable. 我的问题是我除了克隆接口变量之外还有五个变量而不是接口变量。

That will depend entirely on whether WiSeConBaseModel or any of the superclasses between it and Object implement clone and, if they do, what those clone methods do. 这将完全取决于WiSeConBaseModelWiSeConBaseModelObject之间的任何超类是否实现clone以及(如果这样做的话)这些clone方法的作用。

If they don't , then Object#clone is used. 如果不是 ,则使用Object#clone The documentation says: 该文件说:

The method clone for class Object performs a specific cloning operation. 类Object的方法clone执行特定的克隆操作。 First, if the class of this object does not implement the interface Cloneable, then a CloneNotSupportedException is thrown. 首先,如果该对象的类未实现Cloneable接口,则抛出CloneNotSupportedException。 Note that all arrays are considered to implement the interface Cloneable and that the return type of the clone method of an array type T[] is T[] where T is any reference or primitive type. 注意,所有数组都被认为实现了Cloneable接口,并且数组类型T []的clone方法的返回类型为T [],其中T是任何引用或原始类型。 Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; 否则,此方法将创建此对象类的新实例,并使用该对象相应字段的内容完全初始化其所有字段,就像通过赋值一样; the contents of the fields are not themselves cloned. 字段的内容本身不会被克隆。 Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation. 因此,此方法执行此对象的“浅复制”,而不是“深复制”操作。

(my emphasis) (我的重点)

So with Object#clone , that code will end up with the original and the clone both referencing the same object via observer . 因此,使用Object#clone ,该代码将以原始代码和克隆结尾,并且两者都通过observer引用同一对象。

Is there any issue of cloning of an interface object or any other issue? 是否存在克隆接口对象的问题或任何其他问题?

Conceptually, it is not right. 从概念上讲,这是不对的。
You don't clone interfaces. 您不克隆接口。
You clone only instances. 您仅克隆实例。
So it means that in your case you want also to clone the interface implementations. 因此,这意味着您还需要克隆接口实现。

My question is I have five variables other than interface variable while cloning all five variables is getting but not this interface variable. 我的问题是我除了克隆接口变量之外还有五个变量而不是接口变量。

These variables are very probably primitives and the default clone() behavior is "fine" as primitives copy means primitive assignments such as clone.myInt = original.myInt and this doesn't result to a shared myInt variable between the original and the cloned object. 这些变量很可能是基元,默认的clone()行为是“精细”的,因为基元复制意味着原始分配,例如clone.myInt = original.myInt ,这不会导致原始对象和克隆对象之间共享myInt变量。

But this one : 但是这个:

private ValueChangeObserver observer = null;

is not a primitive. 不是原始的。

So as you clone a BaseModelItem instance, the observer field will reference exactly the same object in the original and the cloned object. 因此,当您克隆BaseModelItem实例时, observer字段将引用原始对象和克隆对象中完全相同的对象。

So you should specify how to clone that variable. 因此,您应该指定如何克隆该变量。
You should rather write something like : 您应该写一些类似的内容:

private ValueChangeObserver observer = null;
...
@Override
public WiSeConBaseModelItem clone() {
    WiSeConBaseModelItem clonedItem = (WiSeConBaseModelItem) super.clone();
    cloneItem.observer = observer.clone();
    return clonedItem;
}

So it means you will have to override clone() in each implementation of ValueChangeObserver but you will also have to defined clone() in ValueChangeObserver as it doesn't declare it : 因此,这意味着您将不得不在ValueChangeObserver每个实现中重写clone() ,但还必须在ValueChangeObserver定义clone() ,因为它没有声明它:

public interface ValueChangeObserver {
   onChanged(Object obj);
}

In fact, you should not even use clone() and Cloneable() . 实际上,您甚至都不应该使用clone()Cloneable()
All that should make you realize that overriding clone() is complicate, error prone (and it has also a important limitation for final fields contained by mutable class as you cannot reassigned a final field). 所有这些应该使您认识到,覆盖clone()是复杂的,容易出错(并且对于可变类所包含的final字段也有重要限制,因为您无法重新分配final字段)。

So just forget clone() and favor rather the use of a copy constructor : 因此,只需忘记clone() ,而宁愿使用copy构造函数:

public WiSeConBaseModelItem copy() {
     WiSeConBaseModelItem copy = new WiSeConBaseModelItem(primitiveOne, primitiveTwo, primitiveThree, observer.copy() ...);
     return copy;
}

You may also use reflection libraries to perform copies. 您也可以使用反射库执行复制。
It avoids writing boiler plate code. 它避免了编写样板代码。
Note that the processing time may be a little more important. 请注意,处理时间可能更重要。 So it should be considered. 所以应该考虑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM