To answer your first question, you must implement the Clonable
interface for the clone()
method to work since Object's clone checks that the interface is implemented otherwise it will throw an exception.
Using clone()
is a bad idea. It was one of the original ideas in Java that didn't work out. There are some design issues including it usually being a shallow copy. If you want to make a copy or a deep copy of an object, it's best to create a copy constructor or a copy method to do it without using clone. Using clone() correctly is hard.
If really you want to use the clone()
, then read this blog post which explains how to use clone()
. Basically there are 5 points to remember when using clone()
:
1) Clone method is used to create a copy of object in Java. In order to use clone() method, class must implement java.lang.Cloneable interface and override protected clone() method from java.lang.Object. A call to clone() method will result in CloneNotSupportedException, if that class doesn't implement Cloneable interface.
2) No constructor is called during cloning of Object in Java.
3) Default implementation of clone() method in Java provides "shallow copy" of object, because it creates copy of Object by creating new instance and then copying content by assignment, which means if your Class contains a mutable field, then both original object and clone will refer to same internal object. This can be dangerous, because any change made on that mutable field will reflect in both original and copy object. In order to avoid this, override clone() method to provide deep copy of object.
4) By convention, clone of an instance should be obtained by calling super.clone() method, this will help to preserve invariant of object created by clone() method i.e. clone != original and clone.getClass() == original.getClass(). Though these are not absolute requirement as mentioned in Javadoc.
5) Shallow copy of an instance is fine, until it only contains primitives and Immutable objects, otherwise, you need to modify one or more mutable fields of object returned by super.clone, before returning it to caller.