Valid Java, inclutivejava

Source: Internet
Author: User

Valid Java, inclutivejava

Cloneable interface must be implemented when overwriting clone. Cloneable does not define any method.
What does Cloneable mean?
If a class implements Clonable, the Object's clone method will return the Object's domain-by-domain copy, otherwise it will throwCloneNotSupportedException.


Generally, the interface is implemented to indicate the behavior of the class.
The Cloneable interface changes the behavior of the protected method in the superclass.
This is an atypical usage and is not worth doing.


Now that the clone method is overwritten, we need to follow some conventions:

  • X. clone ()! = X;
  • X. clone (). getClass () = x. getClass ();
  • X. clone (). equals (x );

In addition, we must ensure that the clone result does not affect the original object while ensuring the clone method conventions.


For example, in the following case, the clone method is not overwritten and the result of super. clone () is obtained directly:

import java.util.Arrays;public class Stack implements Cloneable {    private Object[] elements;    private int size = 0;    private static final int DEFAULT_INITIAL_CAPACITY = 16;    public Stack() {        this.elements = new Object[DEFAULT_INITIAL_CAPACITY];    }    public void push(Object e) {        ensureCapacity();        elements[size++] = e;    }    public Object pop() {        if (size == 0)            throw new EmptyStackException();        Object result = elements[--size];        elements[size] = null; // Eliminate obsolete reference        return result;    }    public boolean isEmpty() {        return size == 0;    }    // Ensure space for at least one more element.    private void ensureCapacity() {        if (elements.length == size)            elements = Arrays.copyOf(elements, 2 * size + 1);    }}


As a result, elements in the clone result and elements of the original object reference the same array.

In this case, override the clone method and ensure that the original object is not hurt:

@Overridepublic Stack clone() {    try {        Stack result = (Stack) super.clone();        result.elements = elements.clone();        return result;    } catch (CloneNotSupportedException e) {        throw new AssertionError();    }}

Although elements is cloned separately, the premise of this practice is that elements is not final.
In fact, clone is not compatible with the immutable field that references a mutable object.


If the element of the array is of the reference type, a problem still occurs when an element changes.
Take Hashtable as an example. Elements in Hashtable use their internal class Entry.

private static class Entry<K,V> implements Map.Entry<K,V> {    int hash;    final K key;    V value;    Entry<K,V> next;    protected Entry(int hash, K key, V value, Entry<K,V> next) {        this.hash = hash;        this.key =  key;        this.value = value;        this.next = next;    }    //..}


If you clone elements directly as in the Stack example, the cloned Hashtable changes when an Entry changes.

In Hashtable, clone is overwritten as follows:

/** * Creates a shallow copy of this hashtable. All the structure of the * hashtable itself is copied, but the keys and values are not cloned. * This is a relatively expensive operation. * * @return  a clone of the hashtable */public synchronized Object clone() {    try {        Hashtable<K,V> t = (Hashtable<K,V>) super.clone();        t.table = new Entry[table.length];        for (int i = table.length ; i-- > 0 ; ) {            t.table[i] = (table[i] != null)                ? (Entry<K,V>) table[i].clone() : null;        }        t.keySet = null;        t.entrySet = null;        t.values = null;        t.modCount = 0;        return t;    } catch (CloneNotSupportedException e) {        // this shouldn't happen, since we are Cloneable        throw new InternalError();    }}


Given that clone may cause many problems, we have two suggestions:

  • Do not extend the Cloneable Interface
  • Do not implement the Cloneable interface for classes designed for inheritance

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.