Jun 13, 2011

Using Xstream to Deep Clone Java Object



Sometime, We need to clone an object to save this time status for backup. If using Getter and Setter to copy the value, it must increase the source code. This method is not a good method for clone object. First, you must to know object properties. Second, if this object add more properties. You must rewrite the clone object.

Xstream is a Java library which is handle Java object convert to XML or XML convert to Java object, but also can clone java object (Java object -> XML -> Java object).

Xstream web site: http://xstream.codehaus.org/

When you download complete. Please add .jar to Class Path.

Assume there have are 2 object called: Parent and Info.

Parent class:
package xstream.sample;

public class Parent {

    private String firstName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Parent [firstName=" + firstName + ", lastName=" + lastName
                + "]";
    }

}

Info class:
package xstream.sample;

import java.util.LinkedList;
import java.util.List;

public class Info {

    private String firstName;
    private String lastName;
    private int age;
    private List<String> hobbies;
    private Parent parent;
    
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public void addHobby(String hobby) {
        if (hobbies == null)
            hobbies = new LinkedList<String>();
        hobbies.add(hobby);
    }
    
    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }

    @Override
    public String toString() {
        return "Info [firstName=" + firstName + ", lastName=" + lastName
                + ", age=" + age + ", hobbies=" + hobbies + ", parent="
                + parent + "]";
    }
    
}

Clone function:
package xstream.sample;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class Main {

    private static final XStream XSTREAM = new XStream(new DomDriver());
    
    @SuppressWarnings("unchecked")
    public static <T> T cloneObject(T src){
        return (T) XSTREAM.fromXML(XSTREAM.toXML(src));
    }

}

Test case:
package xstream.sample;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class Main {

    private static final XStream XSTREAM = new XStream(new DomDriver());
    
    public static void main(String[] args) {
        //Create info object
        Info info = new Info();
        Parent parent = new Parent();
        
        //Set data
        info.setFirstName("Lawrence");
        info.setFirstName("Cheung");
        info.setAge(24);
        info.addHobby("Sports");
        info.addHobby("Reading");
        
        parent.setFirstName("Tom");
        parent.setLastName("Cheung");
        info.setParent(parent);
        
        //Print my info
        System.out.println("Original object: " + info);
        
        System.out.println("Now, we are going to clone info object");
        System.out.println();
        Info clonedInfo = cloneObject(info);
        
        //Print cloned info
        System.out.println("Cloned object: " + clonedInfo);
        System.out.println();
        
        //Modify original info
        System.out.println("Change original info age to 25 and parent first name set to John.");
        info.setAge(25);
        info.getParent().setFirstName("John");
        
        System.out.println();
        System.out.println("Original object: " + info);
        System.out.println("Cloned object: " + clonedInfo);
    }
    
    @SuppressWarnings("unchecked")
    public static <T> T cloneObject(T src){
        return (T) XSTREAM.fromXML(XSTREAM.toXML(src));
    }

}


Result:
Original object: Info [firstName=Cheung, lastName=null, age=24, hobbies=[Sports, Reading], parent=Parent [firstName=Tom, lastName=Cheung]]
Now, we are going to clone info object

Cloned object: Info [firstName=Cheung, lastName=null, age=24, hobbies=[Sports, Reading], parent=Parent [firstName=Tom, lastName=Cheung]]

Change original info age to 25 and parent first name set to John.

Original object: Info [firstName=Cheung, lastName=null, age=25, hobbies=[Sports, Reading], parent=Parent [firstName=John, lastName=Cheung]]
Cloned object: Info [firstName=Cheung, lastName=null, age=24, hobbies=[Sports, Reading], parent=Parent [firstName=Tom, lastName=Cheung]]

As you see that. The result display Info and Parent Object also cloned. I changed the original value. The cloned object also not change. So those object pointer are pointed to different address. Perfect Clone!


1 comments:

for IT the said...

I have read your blog its very attractive and impressive. I like it your blog.

Java Training in Chennai Core Java Training in Chennai Core Java Training in Chennai

Java Online Training Java Online Training Core Java 8 Training in Chennai Core java 8 online training JavaEE Training in Chennai Java EE Training in Chennai

Post a Comment

Twitter Delicious Facebook Digg Google Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Best Hostgator Coupon Code