views:

69

answers:

6

Java doc says -

The class Object does not itself implement the interface Cloneable, so calling the clone method on an object whose class is Object will result in throwing an exception at run time.

Which is why clone method in Object class is protected ? is that so ?

That means any class which doesn't implement cloneable will throw CloneNotSupported exception when its clone method is invoked.

I ran a test program

public class Test extends ABC implements Cloneable{

    @Override
    public Object clone() throws CloneNotSupportedException {
        System.out.println("calling super.clone");
            return super.clone();
    }

    public static void main(String[] args) {
        Test t = new Test();
        try{
        t.clone();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class ABC{

}

From Class Test's clone method super.clone is being invoked ?

Why doesn't it throw exception ?

A: 

The Cloneable interface is a marker interface that indicates that the implementing class supports the clone method. The reason that super.clone() doesn't throw an exception is that the base Object it is being called on is Cloneable by inheritance.

From the Javadoc:

A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class.

Invoking Object's clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown.

See: Cloneable (Java Platform SE 6)

richj
+1  A: 

Inheritance tree of the Test instance t looks like

Object
  ABC
    Test

Test also implements Cloneable which means that when you call the method super.clone() Object's clone method will be called. It checks if the instance t implements the Cloneable interface. Since it does implement the method doesn't throw an exception.

Boris Pavlović
A: 

Because your class implements Cloneable. From the Javadoc of Cloneable:

A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class.

So this allows to use Object's clone() method. It is (again according to the Javadoc) just a convention to override clone(). If you do not override it and Object's clone() method performs a field-for-field copy, you might still get a CloneNotSupportedException if one of the fields is itself not cloneable. Therefore it is good advice to override it.

musiKk
A: 

Why is the clone method in Object class protected?

So that a class that chooses to support cloning is not forced to expose it in its public API.

As your example demonstrates, a subclass is allowed to override a method with a more access than the inherited version of the method. You just cannot reduce a method's access this way.

That means any class which doesn't implement cloneable will throw CloneNotSupported exception when its clone method is invoked.

That is correct.

From Class Test's clone method super.clone is being invoked ?

That is correct.

Why doesn't it throw exception ?

Because you have declared that your class implements Cloneable. If you had not done this, it would throw an exception ... assuming that your clone method still called super.clone().

Stephen C
A: 

This might give you the answer to why is the method protected why is clone method protected

It does not throw exception because you implement Cloneable. From the Cloneable documentation:

"A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class. Invoking Object's clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown. "

But as you're implementing it you tell the Object implementation that it's legal to make a field-for-field copy so it does not throw the exception.

celavek
A: 

I would say a good question to confuse the interviewees :).

As far as the reason why it doesn't throw the exception. Think of it in object way. Your t object is of class Test which implements cloneable. When you call the method super.clone it is still an object of class Test and so there is no reason for it to throw CloneNotSupported exception. Had it been an object of class Object itself it would have thrown the exception.

Ankit