How do I copy an object in Java?

后端 未结 23 2436
终归单人心
终归单人心 2020-11-21 04:50

Consider the code below:

DummyBean dum = new DummyBean();
dum.setDummy(\"foo\");
System.out.println(dum.getDummy()); // prints \'foo\'

DummyBean dumtwo = du         


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

    Basic: Object Copying in Java.

    Let us Assume an object- obj1, that contains two objects, containedObj1 and containedObj2.
    enter image description here

    shallow copying:
    shallow copying creates a new instance of the same class and copies all the fields to the new instance and returns it. Object class provides a clone method and provides support for the shallow copying.
    enter image description here

    Deep copying:
    A deep copy occurs when an object is copied along with the objects to which it refers. Below image shows obj1 after a deep copy has been performed on it. Not only has obj1 been copied, but the objects contained within it have been copied as well. We can use Java Object Serialization to make a deep copy. Unfortunately, this approach has some problems too(detailed examples).
    enter image description here

    Possible Problems:
    clone is tricky to implement correctly.
    It's better to use Defensive copying, copy constructors(as @egaga reply) or static factory methods.

    1. If you have an object, that you know has a public clone() method, but you don’t know the type of the object at compile time, then you have problem. Java has an interface called Cloneable. In practice, we should implement this interface if we want to make an object Cloneable. Object.clone is protected, so we must override it with a public method in order for it to be accessible.
    2. Another problem arises when we try deep copying of a complex object. Assume that the clone() method of all member object variables also does deep copy, this is too risky of an assumption. You must control the code in all classes.

    For example org.apache.commons.lang.SerializationUtils will have method for Deep clone using serialization(Source). If we need to clone Bean then there are couple of utility methods in org.apache.commons.beanutils (Source).

    • cloneBean will Clone a bean based on the available property getters and setters, even if the bean class itself does not implement Cloneable.
    • copyProperties will Copy property values from the origin bean to the destination bean for all cases where the property names are the same.
    0 讨论(0)
  • 2020-11-21 05:11

    Use gson for duplicating an object.

    public static <T>T copyObject(Object object){
        Gson gson = new Gson();
        JsonObject jsonObject = gson.toJsonTree(object).getAsJsonObject();
        return gson.fromJson(jsonObject,(Type) object.getClass());
    }
    

    Assume I have an object person.So

    Person copyPerson = copyObject(person);
    

    Note: The performance is much slower.

    0 讨论(0)
  • 2020-11-21 05:13

    You can deep copy automatically with XStream, from http://x-stream.github.io/:

    XStream is a simple library to serialize objects to XML and back again.

    Add it to your project (if using maven)

    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>1.3.1</version>                
    </dependency>
    

    Then

    DummyBean dum = new DummyBean();
    dum.setDummy("foo");
    DummyBean dumCopy = (DummyBean) XSTREAM.fromXML(XSTREAM.toXML(dum));
    

    With this you have a copy without the need to implement any cloning interface.

    0 讨论(0)
  • 2020-11-21 05:15

    Create a copy constructor:

    class DummyBean {
      private String dummy;
    
      public DummyBean(DummyBean another) {
        this.dummy = another.dummy; // you can access  
      }
    }
    

    Every object has also a clone method which can be used to copy the object, but don't use it. It's way too easy to create a class and do improper clone method. If you are going to do that, read at least what Joshua Bloch has to say about it in Effective Java.

    0 讨论(0)
  • 2020-11-21 05:16

    This works too. Assuming model

    class UserAccount{
       public int id;
       public String name;
    }
    

    First add compile 'com.google.code.gson:gson:2.8.1' to your app>gradle & sync. Then

    Gson gson = new Gson();
    updateUser = gson.fromJson(gson.toJson(mUser),UserAccount.class);
    

    You can exclude using a field by using transient keyword after access modifier.

    Note: This is bad practice. Also don't recommend to use Cloneable or JavaSerialization It's slow and broken. Write copy constructor for best performance ref.

    Something like

    class UserAccount{
            public int id;
            public String name;
            //empty constructor
            public UserAccount(){}
            //parameterize constructor
            public UserAccount(int id, String name) {
                this.id = id;
                this.name = name;
            }
    
            //copy constructor
            public UserAccount(UserAccount in){
                this(in.id,in.name);
            }
        }
    

    Test stats of 90000 iteration:
    Line UserAccount clone = gson.fromJson(gson.toJson(aO), UserAccount.class); takes 808ms

    Line UserAccount clone = new UserAccount(aO); takes less than 1ms

    Conclusion: Use gson if your boss is crazy and you prefer speed. Use second copy constructor if you prefer quality.

    You can also use copy constructor code generator plugin in Android Studio.

    0 讨论(0)
  • 2020-11-21 05:17

    In the package import org.apache.commons.lang.SerializationUtils; there is a method:

    SerializationUtils.clone(Object);
    

    Example:

    this.myObjectCloned = SerializationUtils.clone(this.object);
    
    0 讨论(0)
提交回复
热议问题