我有一个实现了clonable接口的类
public class BaseModelItem extends WiSeConBaseModel implements Cloneable{
private ValueChangeObserver observer=null;
//setting interface other values here
@Override
public WiSeConBaseModelItem clone() {
return (WiSeConBaseModelItem) super.clone();
}
}
界面看起来
public interface ValueChangeObserver {
onChanged(Object obj);
}
我的问题是我有五个变量而不是接口变量,而克隆所有五个变量都得到了但不是这个接口变量。
是否存在克隆接口对象或任何其他问题的问题?
提前致谢
答案 0 :(得分:1)
我的问题是我有五个变量而不是接口变量,而克隆所有五个变量都得到了但不是这个接口变量。
这完全取决于WiSeConBaseModel
或Object
与clone
之间的任何超类是否实现clone
,以及Object#clone
方法执行的操作。< / p>
如果他们不,则使用Object#clone
。文档说:
Object类的方法clone执行特定的克隆操作。首先,如果此对象的类未实现Cloneable接口,则抛出CloneNotSupportedException。请注意,所有数组都被认为实现了Cloneable接口,并且数组类型T []的clone方法的返回类型是T [],其中T是任何引用或基本类型。否则,此方法创建此对象的类的新实例,并使用该对象的相应字段的内容初始化其所有字段,就像通过赋值一样;这些字段的内容本身不会被克隆。 因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。
(我的重点)
因此,对于observer
,该代码将以原始代码和克隆结束,并通过indexTitles(for:)
引用同一对象。
答案 1 :(得分:1)
是否存在克隆接口对象或任何其他对象的问题 问题
从概念上讲,这是不对的
你不克隆接口
您只克隆实例
所以这意味着在你的情况下你也想要克隆接口实现。
我的问题是我有五个变量而不是接口变量 虽然克隆所有五个变量但是没有这个接口 变量
这些变量很可能是原语,默认的clone()
行为是&#34;罚款&#34;原语复制意味着原始分配,例如clone.myInt = original.myInt
,这不会导致原始和克隆对象之间的共享myInt
变量。
但是这个:
private ValueChangeObserver observer = null;
不是原始的。
因此,当您克隆BaseModelItem
实例时,observer
字段将引用原始对象和克隆对象中的完全相同的对象。
因此,您应该指定如何克隆该变量 你应该写一些类似的东西:
private ValueChangeObserver observer = null;
...
@Override
public WiSeConBaseModelItem clone() {
WiSeConBaseModelItem clonedItem = (WiSeConBaseModelItem) super.clone();
cloneItem.observer = observer.clone();
return clonedItem;
}
因此,这意味着您必须在clone()
的每个实施中覆盖ValueChangeObserver
,但您还必须在clone()
中定义ValueChangeObserver
,因为它不会声明:
public interface ValueChangeObserver {
onChanged(Object obj);
}
事实上,您甚至不应该使用clone()
和Cloneable()
所有这一切都应该让你意识到覆盖clone()
是复杂的,容易出错(并且它对可变类包含的final
字段也有一个重要的限制,因为你无法重新分配final
字段。
所以请忘记clone()
,而不是使用复制构造函数:
public WiSeConBaseModelItem copy() {
WiSeConBaseModelItem copy = new WiSeConBaseModelItem(primitiveOne, primitiveTwo, primitiveThree, observer.copy() ...);
return copy;
}
您也可以使用反射库来执行复制 它避免编写锅炉板代码 请注意,处理时间可能更重要一些。所以应该考虑它。