Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I know that clone() is a protected method, but "protected" means that it is accessible for all subclasses of particular class.

Any Java class is a subclass of Object, so what is the reason for the protected method here?

And why can we call clone() only on classes that implement the Cloneable interface? I can't understand how it connects to the fact that clone() in Object is declared as protected.

like image 357
Don_Quijote Avatar asked Aug 14 '13 18:08

Don_Quijote


People also ask

Why is object clone () method available only to classes that implement cloneable interface?

The clone() method isn't defined by the Cloneable interface. The clone method in the Object class is protected to prevent a client class from calling it - Only subclasses can call or override clone, and doing so is a bad idea.

Why clone method is not in cloneable interface?

The Cloneable interface itself is empty; it is just a marker interface used by Java to ensure that using the clone method is legal. Doing it this way also removes the ability to make use of generics to ensure type safety: class Foo implements Cloneable { // Valid.

Does cloneable interface contains clone method?

Note: This interface does not contain the clone method.

Why do we need to implement a cloneable interface?

A class must implement the Cloneable interface if we want to create the clone of the class object. The clone() method of the Object class is used to create the clone of the object. However, if the class doesn't support the cloneable interface, then the clone() method generates the CloneNotSupportedException.


1 Answers

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); }
}
like image 185
Cephalopod Avatar answered Sep 22 '22 18:09

Cephalopod