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:02

I use Google's JSON library to serialize it then create a new instance of the serialized object. It does deep copy with a few restrictions:

  • there can't be any recursive references

  • it won't copy arrays of disparate types

  • arrays and lists should be typed or it won't find the class to instantiate

  • you may need to encapsulate strings in a class you declare yourself

I also use this class to save user preferences, windows and whatnot to be reloaded at runtime. It is very easy to use and effective.

import com.google.gson.*;

public class SerialUtils {

//___________________________________________________________________________________

public static String serializeObject(Object o) {
    Gson gson = new Gson();
    String serializedObject = gson.toJson(o);
    return serializedObject;
}
//___________________________________________________________________________________

public static Object unserializeObject(String s, Object o){
    Gson gson = new Gson();
    Object object = gson.fromJson(s, o.getClass());
    return object;
}
       //___________________________________________________________________________________
public static Object cloneObject(Object o){
    String s = serializeObject(o);
    Object object = unserializeObject(s,o);
    return object;
}
}
查看更多
泛滥B
3楼-- · 2018-12-31 01:02

Yes. You need to Deep Copy your object.

查看更多
素衣白纱
4楼-- · 2018-12-31 01:08

Use a deep cloning utility:

SomeObjectType copy = new Cloner().deepClone(someObject);

This will deep copy any java object, check it out at https://github.com/kostaskougios/cloning

查看更多
低头抚发
5楼-- · 2018-12-31 01:10

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.
查看更多
呛了眼睛熬了心
6楼-- · 2018-12-31 01:10

To do that you have to clone the object in some way. Although Java has a cloning mechanism, don't use it if you don't have to. Create a copy method that does the copy work for you, and then do:

dumtwo = dum.copy();

Here is some more advice on different techniques for accomplishing a copy.

查看更多
高级女魔头
7楼-- · 2018-12-31 01:11

If you can add an annotation to the source file, an annotation processor or code generator like this one can be used.

import net.zerobuilder.BeanBuilder

@BeanBuilder
public class DummyBean { 
  // bean stuff
}

A class DummyBeanBuilders will be generates, which has a static method dummyBeanUpdater to create shallow copies, the same way as you would do it manually.

DummyBean bean = new DummyBean();
// Call some setters ...
// Now make a copy
DummyBean copy = DummyBeanBuilders.dummyBeanUpdater(bean).done();
查看更多
登录 后发表回答