伙计们,尽管这听起来像是一个已经被问到的问题,但事实并非如此。
这里的问题很简单,我想在不使用克隆、复制构造函数和复制工厂方法的情况下创建对象的精确副本,因为我们无法对类进行更改(无权限)。假设我有一个 Dog 对象
我想再创建一个 Dog 对象,在这个副本中我必须更改某些属性的值,但原始对象不应受到任何影响
谢谢
伙计们,尽管这听起来像是一个已经被问到的问题,但事实并非如此。
这里的问题很简单,我想在不使用克隆、复制构造函数和复制工厂方法的情况下创建对象的精确副本,因为我们无法对类进行更改(无权限)。假设我有一个 Dog 对象
我想再创建一个 Dog 对象,在这个副本中我必须更改某些属性的值,但原始对象不应受到任何影响
谢谢
如果对象支持,您可以考虑序列化/反序列化,但这可能会影响性能。
使用 ObjectOutputStream 也是另一种选择:http
://docs.oracle.com/javase/6/docs/api/java/io/ObjectOutputStream.html#replaceObject%28java.lang.Object%29
另请查看“第 76 项:写入防御性地读取对象方法”的“有效 Java”。它展示了您可以使用对象输入流玩的一些讨厌的技巧。
1) 使用 Apache Beanutils
Object cloned = BeanUtils.cloneBean(obj);//pass object for cloning
2)使用反射
public <T> T clone(T obj1) {
try {
Class clazz = obj1.getClass();
T obj2 = (T) clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
int modifiers = field.getModifiers();
if (!Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
field.set(obj2, field.get(obj1));
}
} catch (IllegalArgumentException | IllegalAccessException ex) {
return null;
}
}
return obj2;
} catch (InstantiationException | IllegalAccessException ex) {
return null;
}
}
你可以创建一个新的对象来NewDog
使用OldDog
你考虑过这样的事情吗?
NewDog dog = new NewDog(someOldDogObject);
而构造函数NewDog
可以。
public NewDog(OldDog oldDog){
this.dogWeight = oldDog.dogWeight; // keeping the same weight
this.dogName = "newDog" + oldDog.dogName; // changing your dog name as per rquirement.
}
您可以使用辅助类/方法:
MyObject cloneMyObject(MyObject o) {
MyObject cloned = new MyObject();
cloned.fieldOne = o.fieldOne;
cloned.fieldTwo = o.fieldTwo;
// Or this depending on how MyObject was implemented
// cloned.setFieldOne(o.getFieldOne());
// cloned.setFieldTwo(o.getFieldTwo());
return cloned;
}
附带说明,要获得深度克隆的对象,请确保在将所有引用类型添加到新对象之前对其进行克隆。
您可以创建一个 util 方法来为您执行此操作,就像这样
public class MyDogUtils {
public Dog copy(final Dog res, final Dog dest) {
final Dog ret = (dest == null) ? new Dog() : dest;
ret.setName(res.getName());
// some code here
return ret;
}
}