How to clone values from an object

4

How can we make an object equal to an object's "values"?

Since my object has other objects, and lists of other objects.

    
asked by anonymous 24.09.2015 / 21:07

1 answer

3

There are basically two options (actually three, the third being "implement everything yourself"):

  • Implement the interface Cloneable

    Every Java object has a clone method, which is able to make shallow copies of that object. This method is protected , so it is usually not accessible. However, if you have the class implement Cloneable and override the clone method with the public modifier, then this method can be used to make such copies (in principle you do not even have to implement anything, Java itself does the "magic" for you):

    public class MinhaClasse implements Cloneable {
        private int x;
        private String y;
        private float z;
    
        public Object clone() {
            return super.clone();
        }
    }
    

    The problem with this method is that, as I said, it makes shallow copies - if you have references to other objects, and lists other objects, the clone will still reference the old objects. Therefore it is necessary to implement own logic in the clone method, which is not very convenient ...

  • Serialize your object and then deserialize it to another object

    A preferred option is to use one of the Java serialization tools to transform your object into a byte array (or a string) and then turn it back into an object. A simple (but not necessarily the most efficient) way is through ObjectInputStream and ObjectOutputStream :

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(objeto);
    
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bais);
    Object clone = ois.readObject();
    

    This will make a deep copy, also copying each referenced object, recursively, until all the "object graph" has been copied (and what is best, keeping the right references, ie if A points to B and C , and both B and C point to D , a single D clone is created, referenced by the B and C clones.

    For this to be possible, your class needs to implement Serializable , and only. At first, nothing else needs to be done on your part (except ensuring that every referenced object also implements Serializable - but many of Java's built-in objects already do ).

    Just be careful not to serialize more than you want - if your object references others, referencing others, etc., it's all too easy to suddenly have the entire memory of your program cloned at one time ... To avoid this , use the transient modifier in the fields should not be serialized, and then they will be ignored (returning as null after deserialization):

    public class MinhaClasse implements Serializable {
        private int x;
        private String y;
        private float z;
    
        private MinhaOutraClasse a; // Precisa também ser Serializable
        private OutraClasse[] b;    // idem
        private transient NaoCloneEsta c; // Não precisa ser, tanto faz
    }
    
  • 24.09.2015 / 23:30