我想要克隆一个给定的对象。
如果我这样做
public class Something{
Object o; //set in the constructor
public Something(Object o){
this.o = o;}
public Something clone() throws CloneNotSupportedException{
Something temp = super.clone();
if (o instanceof Cloneable) //important part
temp.o = o.clone(); //important part
else temp.o = o;
}
}
这不起作用,因为o.clone()受到保护。
如果我这样做
if (o instanceof Cloneable) //important part
temp.o = ((Cloneable)o).clone(); //important part
它不会起作用,因为Cloneable是一个空接口。
那么我如何说服编译器你可以克隆o?
答案 0 :(得分:2)
你不能,在实现clone()时必须知道什么是克隆,必须知道实现类。
克隆的替代方法是使用具有相同问题的复制构造函数,您必须知道该类。
有人说不要使用克隆,其他人说要定义你自己的界面,例如:object Animals
http://c2.com/cgi/wiki?CloneableDoesNotImplementClone
答案 1 :(得分:2)
替代方案是使用序列化,如果它可以实现Serializable接口。下行是表现的。
如果你不想使用apache commons,你可以使用ObjectOutputStream / ObjectInputStream做同样的事情。
答案 2 :(得分:1)
你可以用反射
来做//We need reflection
import java.lang.reflect.*;
//This class is the backbone of the feature
public class MyCloneable implements Cloneable {
//A constructor. For the sake of simplicity, the constructor is an empty constructor.
public MyCloneable() {}
//We implement the clone method. This returns a clone
protected Object clone() throws CloneNotSupportedException {
//We need the class of the object
class c = this.getClass();
//We get the empty constructor of the object
Constructor constructor = c.getConstructor(new Class[]{});
//newClone will be the cloned object
Object newClone = constructor.newInstance(new Object[]{});
//We get the array of fields
Field[] fields = c.getDeclaredFields();
//We iterate the fields to copy them. You might want to close these too, but for the sake of simplicity I did not tackle with this issue
for (int fieldIndex = 0; fieldIndex < fields.length; fieldIndex++) {
//We copy the field values of this into the clone
fields[fieldIndex].set(newClone, fields[fieldIndex].get(this));
}
//newClone is ready and kicking
return newClone;
}
//We need this method to be able to reach the clone method publicly
public Object runClone() throws CloneNotSupportedException {
return this.clone();
}
}
此代码未经测试,欢迎任何观察。
您需要使用从MyCloneable继承的类的对象。
答案 3 :(得分:0)
没有通用的方法来克隆Java中的对象。该类型必须在其公共API中提供克隆方法(可以称为clone()
或其他内容;无关紧要),并且Java中没有这种类型的常用超类型。
答案 4 :(得分:-1)
java.lang.Cloneable
接口必须由我们要创建其对象克隆的类实现。如果我们不实施Cloneable接口,clone()
方法会生成CloneNotSupportedException
。
clone()
方法在Object类中定义。 clone()
方法的语法如下:
protected Object clone() throws CloneNotSupportedException
所以你的班级应该是
public class Something implements Cloneable {
private Object o; //set in the constructor
public Something(Object o) {
this.o = o;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Object getObject() {
return o;
}
public static void main(String[] args) {
Something s = new Something("try");
System.out.println(s.getObject());
try {
Something s2 = (Something) s.clone();
System.out.println(s2.getObject());
} catch (CloneNotSupportedException ex) {
Logger.getLogger(Something.class.getName()).log(Level.SEVERE, null, ex);
}
}
}