Why Is the Clone() Method Protected in Java.Lang.Object

Why is the clone() method protected in java.lang.Object?

The fact that clone is protected is extremely dubious - as is the fact that the clone method is not declared in the Cloneable interface.

It makes the method pretty useless for taking copies of data because you cannot say:

if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}

I think that the design of Cloneable is now largely regarded as a mistake (citation below). I would normally want to be able to make implementations of an interface Cloneable but not necessarily make the interface Cloneable (similar to the use of Serializable). This cannot be done without reflection:

ISomething i = ...
if (i instanceof Cloneable) {
//DAMN! I Need to know about ISomethingImpl! Unless...
copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}

Citation From Josh Bloch's Effective Java:

"The Cloneable interface was intended as a mixin interface for objects to advertise that they permit cloning. Unfortunately it fails to serve this purpose ... This is a highly atypical use of interfaces and not one to be emulated ... In order for implementing the interface to have any effect on a class, it and all of its superclasses must obey a fairly complex, unenforceable and largely undocumented protocol"

Why doesn't the java.lang.Object class clone() method have a body?

 protected native Object clone() throws CloneNotSupportedException;

This is the prototype of clone method in Object class

why no Body ?

It is a native method so it doesn’t have the body cause it’s body is provided by native library which is written in c language same as Jvm
Or we can say we just need to give instruction to the jvm that we need to clone and the rest is taken care by Jvm

Why protected why not public?

Now clone() method is given as protected not public so that we couldn't clone Object class object

This behaviour provided to the sub classes or the classes created by the users .And we know that protected members are accessible outside the package inside
Subclass only and on subclass object only.

why override?

We override it in subclass because there is a possibility that we need to call clone method outside the class and because of protected Behaviour we won’t be able to do that, so we override it with public modifier …prototype mentioned below

public Object clone() throws CloneNotSupportedException;

why object need to be cloneable?

Since the cloning object is done by Jvm so there jvm need a information like on which object cloning is required and for that object is required to have cloneable signature ,
And for that we need to implement cloneable interface which is a marker interface and it will inform to jvm that this specific object need cloning

Why Object clone() method available only to classes that implement Cloneable interface?

Object's clone() method is quite special, as it always returns an instance of the current class that has all fields copied (even final). I don't think its possible to reproduce this with plain Java code, not even with reflection.

Because of this, it must be made available to all classes, but since it should not be callable from the outside by default because you don't want everything to be cloneable, it must be protected.

As an additional check, clone checks that the class implements Cloneable, only to ensure you don't clone non-cloneables by accident.


All in all, cloning is somewhat broken because it doesn't work when you need to deep-copy final fields. I recommend you implement instance copying manually, following this pattern.

public class Base {

/** one or more public constructors */
public Base() { ... }

/** copy-constructor */
protected Base(Base src) { /* copy or deep-copy the state */ }

public Base copy() { return new Base(this); }
}

public class Derived extends Base {

/** one or more public constructors */
public Derived() { ... }

/** copy-constructor */
protected Derived(Derived src) {
super(src);
/* copy or deep-copy the state */
}

@Override
public Derived copy() { return new Derived(this); }
}

Why java.lang.Object can not be cloned?

Because clone is protected in the Object class. It's not public.

The only way to get access to an object's clone() method is to know it has a compile-time type that has a public clone() method.

Why to override clone method in Java

As every class in Java extends from Object, so it should have clone
method but still we are forced to override clone

No you are not forced to override the clone method. In inheritance, when you inherit a class, you are not forced to override it's method. Its modifier being public or protected doesn't make much of a difference. However, if you want to invoke a method directly on super class reference, then that method has to be public. Protected methods are accessible only through inheritance. That is you can only access them through subclass reference. Or if you override the method, you can access them through super keyword.

Having said that, you should not override clone method, as it is broken. Because, for a class to be cloned, you need to implement the Cloneable interface. And then your class uses the clone method of Object class instead. Because, Cloneable interface doesn't exactly have any method for cloning. It would be a better option to use Copy Constructor instead.

public class A {
private int data;
public A() {
}

public A(A a) {
this.data = a.data;
}
}

For more details, I would suggest to go through this chapter of Joshua Bloch's Effective Java, which covers all aspects of using clone method.

Effective Java- Item # 11 - Override clone judiciously



Related Topics



Leave a reply



Submit