How do you make a deep copy of an object?

前端 未结 19 1875
执念已碎
执念已碎 2020-11-21 23:09

It\'s a bit difficult to implement a deep object copy function. What steps you take to ensure the original object and the cloned one share no reference?

相关标签:
19条回答
  • 2020-11-21 23:54

    You can do a serialization-based deep clone using org.apache.commons.lang3.SerializationUtils.clone(T) in Apache Commons Lang, but be careful—the performance is abysmal.

    In general, it is best practice to write your own clone methods for each class of an object in the object graph needing cloning.

    0 讨论(0)
  • 2020-11-21 23:54

    I used Dozer for cloning java objects and it's great at that , Kryo library is another great alternative.

    0 讨论(0)
  • 2020-11-21 23:55

    You can make a deep copy with serialization without creating files.

    Your object you wish to deep copy will need to implement serializable. If the class isn't final or can't be modified, extend the class and implement serializable.

    Convert your class to a stream of bytes:

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(object);
    oos.flush();
    oos.close();
    bos.close();
    byte[] byteData = bos.toByteArray();
    

    Restore your class from a stream of bytes:

    ByteArrayInputStream bais = new ByteArrayInputStream(byteData);
    (Object) object = (Object) new ObjectInputStream(bais).readObject();
    
    0 讨论(0)
  • 2020-11-21 23:55

    Here is an easy example on how to deep clone any object: Implement serializable first

    public class CSVTable implements Serializable{
        Table<Integer, Integer, String> table; 
        public CSVTable() {
            this.table = HashBasedTable.create();
        }
        
        public CSVTable deepClone() {
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(this);
    
                ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bais);
                return (CSVTable) ois.readObject();
            } catch (IOException e) {
                return null;
            } catch (ClassNotFoundException e) {
                return null;
            }
        }
    
    }
    

    And then

    CSVTable table = new CSVTable();
    CSVTable tempTable = table.deepClone();
    

    is how you get the clone.

    0 讨论(0)
  • 2020-11-21 23:57

    One way to implement deep copy is to add copy constructors to each associated class. A copy constructor takes an instance of 'this' as its single argument and copies all the values from it. Quite some work, but pretty straightforward and safe.

    EDIT: note that you don't need to use accessor methods to read fields. You can access all fields directly because the source instance is always of the same type as the instance with the copy constructor. Obvious but might be overlooked.

    Example:

    public class Order {
    
        private long number;
    
        public Order() {
        }
    
        /**
         * Copy constructor
         */
        public Order(Order source) {
            number = source.number;
        }
    }
    
    
    public class Customer {
    
        private String name;
        private List<Order> orders = new ArrayList<Order>();
    
        public Customer() {
        }
    
        /**
         * Copy constructor
         */
        public Customer(Customer source) {
            name = source.name;
            for (Order sourceOrder : source.orders) {
                orders.add(new Order(sourceOrder));
            }
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    Edit: Note that when using copy constructors you need to know the runtime type of the object you are copying. With the above approach you cannot easily copy a mixed list (you might be able to do it with some reflection code).

    0 讨论(0)
  • 2020-11-21 23:58
    import com.thoughtworks.xstream.XStream;
    
    public class deepCopy {
        private static  XStream xstream = new XStream();
    
        //serialize with Xstream them deserialize ...
        public static Object deepCopy(Object obj){
            return xstream.fromXML(xstream.toXML(obj));
        }
    }
    
    0 讨论(0)
提交回复
热议问题