这里的问题很简单,我想在不使用克隆,复制构造函数和复制工厂方法的情况下创建对象的精确副本,因为我们无法对类进行更改(无权限)。 假设我有一个Dog对象
我想再创建一个Dog对象,在这个副本中我必须更改某些属性的值,但原始对象不应该以任何方式受到影响
由于
答案 0 :(得分:4)
如果对象支持序列化/反序列化,则可以考虑序列化/反序列化,但它可能在性能上很重要。
使用ObjectOutputStream也是另一种选择:http://docs.oracle.com/javase/6/docs/api/java/io/ObjectOutputStream.html#replaceObject%28java.lang.Object%29
另请参阅“有效Java”的“项目76:防御性地编写readObject方法”。它显示了一些可以使用对象输入流进行的讨厌技巧。
答案 1 :(得分:1)
您可以使用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.
}
答案 2 :(得分:1)
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;
}
}
答案 3 :(得分:0)
您可以使用辅助类/方法:
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;
}
作为旁注,要获取深度克隆对象,请确保在将所有引用类型添加到新对象之前克隆它们。
答案 4 :(得分:0)
您可以创建一个可以为您执行此操作的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;
}
}