Copy an object in Java

后端 未结 7 443
伪装坚强ぢ
伪装坚强ぢ 2020-12-09 03:41

I have an object that I need to copy in Java. I need to create a copy and run some tests on it without changing the original object itself.

I assumed that I needed t

相关标签:
7条回答
  • 2020-12-09 04:03

    You can use org.apache.commons.lang3.SerializationUtils class for object cloning, - Class should implement Serializable interface.

    • ClassName copyobject = SerializationUtils.clone(classobjectTocopy)

    SerializationUtils.clone is also supported on Google App Engine instance

    0 讨论(0)
  • 2020-12-09 04:04

    There are multiple ways to copy object in java(shallow or deep).
    This Answer will help you.

    0 讨论(0)
  • 2020-12-09 04:16

    For test code Serialization is maybe the safest answer, especially if the object is already Serializable try Apache Commons SerializationUtils for an implementation.

    0 讨论(0)
  • 2020-12-09 04:18

    Joshua Bloch has some interesting things to say about cloneable. Depending on the size/construction of the object, I'd add a copy constructor to the object, or serialise/deserialise using one of the solutions mentioned above.

    0 讨论(0)
  • 2020-12-09 04:19

    Some options:

    • You can implement Cloneable for your object and put clone() method as public. See full explanation here: http://www.cafeaulait.org/course/week4/46.html
      However, this produces a shallow copy and might be not something you want.
    • You can serialize and deserialize your object. You will need to implement Serializable interface for the object and all its fields.
    • You can use XStream to perform serialization via XML - you won't have to implement anything here.
    0 讨论(0)
  • 2020-12-09 04:21

    There are two popular approaches. One is to provide a clone method as you mentioned, like so.

    public class C implements Cloneable {
        @Override public C clone() {
            try {
                final C result = (C) super.clone();
                // copy fields that need to be copied here!
                return result;
            } catch (final CloneNotSupportedException ex) {
                throw new AssertionError();
            }
    }
    

    Pay attention to the "copy fields ... here!" part. The initial result is only a shallow copy, meaning that if there's a reference to an object, both the original and result will share the same object. For example, if C contains private int[] data you'd probably want to copy that.

    ...
    final C result = (C) super.clone();
    result.data = data.clone();
    return result;
    ...
    

    Note that you don't need to copy primitive fields, as their content is already copied, or immutable objects, as they can't change anyways.

    The second approach is to provide a copy constructor.

    public class C {
        public C(final C c) {
            // initialize this with c
        }
    }
    

    Or a copy factory.

    public class C {
        public static C newInstance(final C c) {
            return new C(c);
        }
    
        private C(final C c) {
            // initialize this with c
        }
    }
    

    Both approaches have their respective properties. clone is nice because its a method, so you don't have to know the exact type. In the end, you should always end up with a "perfect" copy. The copy constructor is nice because the caller has a chance to decide, as can be seen by the Java Collections.

    final List c = ... 
    // Got c from somewhere else, could be anything.
    // Maybe too slow for what we're trying to do?
    
    final List myC = new ArrayList(c);
    // myC is an ArrayList, with known properties
    

    I recommend choosing either approach, whichever suits you better.

    I'd use the other approaches, like reflective copying or immediate serializing/deserializing, in unit tests only. To me, they feel less appropriate for production code, mainly because of performance concerns.

    0 讨论(0)
提交回复
热议问题