shtuken
shtuken

Reputation: 161

How to deep copy an object of type Object?

Normally when I deep copy objects I use a copy constructor. For our assignment we are supposed to make an ObjectList, even though the instructor noted that such a list is unwise to use. Anyways, I've run into an issue when I am adding a new Object to the array. I am trying to create a deep copy of the Object before adding it to the array to prevent a privacy leak, but there is no copy constructor for the Object class. For example, the following does not work:

Object temp = new Object(insertObjectArgument);

I then looked into Object.clone(), but it looks like I should stay as far away from that as possible. Is there some way I can deep copy an object of type Object?

Upvotes: 1

Views: 2670

Answers (3)

zeroboo
zeroboo

Reputation: 8955

For complicated objects and when performance is not significant i use a json library, like gson to serialize the object to json text, then deserialize the text to get new object.

gson which based on reflection will works in most cases, except that transient fields will not be copied and objects with circular reference with cause StackOverflow exception.

public static <ObjectType> ObjectType Copy(ObjectType AnObject, Class<ObjectType> ClassInfo)
{
    Gson gson = new GsonBuilder().create();
    String text = gson.toJson(AnObject);
    ObjectType newObject = gson.fromJson(text, ClassInfo);
    return newObject;
}
public static void main(String[] args)
{
    MyObject anObject ...
    MyObject copyObject = Copy(o, MyObject.class);

}

Upvotes: 2

Riley Carney
Riley Carney

Reputation: 860

You need to make a method called clone and override it for the typical clone() method that comes with the Object class using @Override. After this, make a new object, and copy the data from the old object into it. Where I put /... means that more code can be added or you can take away the code I originally put.

/**
 *  Explanation for http://stackoverflow.com/questions/35120424/how-to-deep-copy-an-object-of-type-object
 * 
 * @author Riley C
 * @version 1/31/16
 */
public class ObjectToReturn
{
    //variables
    int x;
    int y;
    // ...

    //constructor
    public ObjectToReturn()
    {
        x = 0;
        y = 0;
        // ...
    }

    //overrides
    @Override
    public ObjectToReturn clone()
    {
        ObjectToReturn returnMe = new ObjectToReturn();
        returnMe.setX(this.x);
        returnMe.setY(this.y);
        // ...
        return returnMe;
    }

    //methods
    public void setX(int x) {this.x = x;}
    public void setY(int y) {this.y = y;}
    // ...

    public int getX() {return x;}
    public int getY() {return y;}
    // ...
}

Why you shouldn't use the default clone

From what I can remember, while clone() can sometimes generate a deep copy of an Object, it doesn't always do it.

Habits to get into

Good habits my college instructor said his company liked to see if making sure you make deep copies of arrays and objects, as well as overriding the equals, clone, and toString method which typically come with the class Object. This will allow you to use these methods on your objects with how you would like them to work, instead of the default values which may give answers that make no sense. It also is often cleaner, and is prone to throw less errors.

Upvotes: 0

bmargulies
bmargulies

Reputation: 100013

Java has no 'magic' utility for deep copying. If the objects you are concerned with are of classes that chose to support clone(), you can use clone. However, without reading all the code, it's impossible to be sure that the implementations of the clone methods will satisfy your security requirements. Otherwise, you have to do it the hard way, building a new object graph from the old one.

Upvotes: 0

Related Questions