Home » Core Java » Why Object class clone method is protected.

Why Object class clone method is protected.

This is one of the tricky but frequently asked question.

Objects class’s clone method is protected and by default clone method is not visible and not available outside the class, there must be some reason behind this design. The reason is before making clone method available to use; a class has to implement  Cloneable interface first and override its clone method and then it is the responsibility of the class to expose this method through any other public method or by making the @Overriden clone method itself public.

SALLOW or DEEP Cloning?

Object class provide implementation of clone method and by default it provides SHALLOW  cloning , it simply creates a new instance and simply copies all the fields into new instance.  Standard way of providing Shallow cloning is to call super.clone() from the overridden clone method, that’s all it will do the job for you. Note all primitive data would get copy but  if there are any object   fields in your class then only their reference would be copied to the cloned object .


@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}

If you want to deep cloning in that case you need to override  the clone  method  and need to  give your own implementation of clone. Rather calling super.clone you  have to copy all NON MUTABLE  fields explicitly.

Typical example here you can see class Person contains object of class Mobile which further hold a Map collection. While doing Deep cloning of Person class we need to explicitly tell clone method to create new objects for its MUATBLE fields: Student and phonebook MAP. So we can not pass their reference during DEEP cloning.

//Deep Cloning Example
class Mobile{
	int mobileNo;
	Map<String, Integer> phoneBook;
	Mobile(int mobileNo,Map<String, Integer> phoneBook ){
		this.mobileNo=mobileNo;
		this.phoneBook=phoneBook;
	}

}
class Person{
	int age;
	String name;
	Mobile mobile;
	public Person(int age, String name, Mobile mobile) {
		super();
		this.age = age;
		this.name = name;
		this.mobile = mobile;
		System.out.println("Constrct call P1");
	}

//	@Override
//	public Object clone() throws CloneNotSupportedException {
//		return super.clone();
//	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		Map<String, Integer> newphoneBook = new HashMap<String, Integer>();
		//copy content of phoneBook
		for(String key : this.mobile.phoneBook.keySet() ){
			newphoneBook.put(key, this.mobile.phoneBook.get(key).intValue());
		}
		//create new mobile object with copied value of phone book
		Mobile mobile = new Mobile(this.mobile.mobileNo, this.mobile.phoneBook);
		//create new instance of person and copy these new field values
		return new Person(this.age, this.name, this.mobile);
	}

}

What is the purpose of calling Super.clone() from clone method?

By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object) obey this convention, it will be the case thatx.clone().getClass() == x.getClass(). This way you do not need to implement clone method for shallow cloning.

By convention, the object returned by this method should be independent of this object (which is being cloned). To achieve this independence, it may be necessary to modify one or more fields of the object returned by super.clone before returning it. Typically, this means copying any mutable objects that comprise the internal “deep structure” of the object being cloned and replacing the references to these objects with references to the copies. If a class contains only primitive fields or references to immutable objects, then it is usually the case that no fields in the object returned by super.cloneneed to be modified.

The method clone for class Object performs a specific cloning operation. First, if the class of this object does not implement the interface Cloneable, then a CloneNotSupportedException is thrown. Note that all arrays are considered to implement the interface Cloneable. Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a “shallow copy” of this object, not a “deep copy” operation.

Ref:http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#clone()

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: