How do I copy an object in Java?

2018-12-31 00:49发布

Consider the code below:

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

DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'

dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'

So, I want to copy the dum to dumtwo and change dum without affecting the dumtwo. But the code above is not doing that. When I change something in dum, the same change is happening in dumtwo also.

I guess, when I say dumtwo = dum, Java copies the reference only. So, is there any way to create a fresh copy of dum and assign it to dumtwo?

21条回答
旧时光的记忆
2楼-- · 2018-12-31 01:12

Here's a decent explanation of clone() if you end up needing it...

Here: clone (Java method)

查看更多
唯独是你
3楼-- · 2018-12-31 01:12

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.

查看更多
宁负流年不负卿
4楼-- · 2018-12-31 01:12
public class MyClass implements Cloneable {

private boolean myField= false;
// and other fields or objects

public MyClass (){}

@Override
public MyClass clone() throws CloneNotSupportedException {
   try
   {
       MyClass clonedMyClass = (MyClass)super.clone();
       // if you have custom object, then you need create a new one in here
       return clonedMyClass ;
   } catch (CloneNotSupportedException e) {
       e.printStackTrace();
       return new MyClass();
   }

  }
}

and in your code:

MyClass myClass = new MyClass();
// do some work with this object
MyClass clonedMyClass = myClass.clone();
查看更多
笑指拈花
5楼-- · 2018-12-31 01:13

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.

查看更多
皆成旧梦
6楼-- · 2018-12-31 01:14

Other than explicitly copying, another approach is to make the object immutable (no set or other mutator methods). In this way the question never arises. Immutability becomes more difficult with larger objects, but that other side of that is that it pushes you in the direction of splitting into coherent small objects and composites.

查看更多
妖精总统
7楼-- · 2018-12-31 01:15

Add Cloneable and below code to your class

public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

Use this clonedObject = (YourClass) yourClassObject.clone();

查看更多
登录 后发表回答