1

伙计们,尽管这听起来像是一个已经被问到的问题,但事实并非如此。

这里的问题很简单,我想在不使用克隆、复制构造函数和复制工厂方法的情况下创建对象的精确副本,因为我们无法对类进行更改(无权限)。假设我有一个 Dog 对象

我想再创建一个 Dog 对象,在这个副本中我必须更改某些属性的值,但原始对象不应受到任何影响

谢谢

4

5 回答 5

4

如果对象支持,您可以考虑序列化/反序列化,但这可能会影响性能。
使用 ObjectOutputStream 也是另一种选择:http
://docs.oracle.com/javase/6/docs/api/java/io/ObjectOutputStream.html#replaceObject%28java.lang.Object%29 另请查看“第 76 项:写入防御性地读取对象方法”的“有效 Java”。它展示了您可以使用对象输入流玩的一些讨厌的技巧。

于 2013-07-16T09:36:46.957 回答
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;
            }
        }
于 2013-07-16T09:45:07.467 回答
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.

}
于 2013-07-16T09:36:17.937 回答
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;
}

附带说明,要获得深度克隆的对象,请确保在将所有引用类型添加到新对象之前对其进行克隆。

于 2013-07-16T09:45:53.107 回答
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;
       }
   }
于 2013-07-16T09:51:23.007 回答