How to properly override clone method?

后端 未结 9 2160
时光说笑
时光说笑 2020-11-22 12:06

I need to implement a deep clone in one of my objects which has no superclass.

What is the best way to handle the checked CloneNotSupportedException thr

相关标签:
9条回答
  • 2020-11-22 12:53

    You can implement protected copy constructors like so:

    /* This is a protected copy constructor for exclusive use by .clone() */
    protected MyObject(MyObject that) {
        this.myFirstMember = that.getMyFirstMember(); //To clone primitive data
        this.mySecondMember = that.getMySecondMember().clone(); //To clone complex objects
        // etc
    }
    
    public MyObject clone() {
        return new MyObject(this);
    }
    
    0 讨论(0)
  • 2020-11-22 12:53
    public class MyObject implements Cloneable, Serializable{   
    
        @Override
        @SuppressWarnings(value = "unchecked")
        protected MyObject clone(){
            ObjectOutputStream oos = null;
            ObjectInputStream ois = null;
            try {
                ByteArrayOutputStream bOs = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(bOs);
                oos.writeObject(this);
                ois = new ObjectInputStream(new ByteArrayInputStream(bOs.toByteArray()));
                return  (MyObject)ois.readObject();
    
            } catch (Exception e) {
                //Some seriouse error :< //
                return null;
            }finally {
                if (oos != null)
                    try {
                        oos.close();
                    } catch (IOException e) {
    
                    }
                if (ois != null)
                    try {
                        ois.close();
                    } catch (IOException e) {
    
                    }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 12:56

    As much as the most of the answers here are valid, I need to tell that your solution is also how the actual Java API developers do it. (Either Josh Bloch or Neal Gafter)

    Here is an extract from openJDK, ArrayList class:

    public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }
    

    As you have noticed and others mentioned, CloneNotSupportedException has almost no chance to be thrown if you declared that you implement the Cloneable interface.

    Also, there is no need for you to override the method if you don't do anything new in the overridden method. You only need to override it when you need to do extra operations on the object or you need to make it public.

    Ultimately, it is still best to avoid it and do it using some other way.

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