在java w / o clone中创建对象的副本,复制构造函数和复制工厂

时间:2013-07-16 09:31:06

标签: java

虽然这可能听起来像是一个已经被问到的问题,但事实并非如此。

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

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

由于

5 个答案:

答案 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)

您可以使用NewDogOldDog创建新对象 你考虑过这样的事吗?

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;
       }
   }