Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java: clone method violation

Code behind:

class A implements Cloneable
{
    int i, j;

    A(int i, int j)
    {
        this.i = i;
        this.j = j;
    }

    A()
    {
    }
}

class B extends A
{
    int l, m;

    B()
    {
    }

    B(int l, int m)
    {
        this.l = l;
        this.m = m;

    }

    public static void main(String l[])
    {
        A obj = new A(1, 2);
        B obj1 = (B) obj.clone(); // ERROR
    }
}

I know that I am violating the meaning of clone as I am trying to assign the fields of one object to a completely different object. But its the error statement that is confusing me.

Statement: "error: clone() has protected access in Object"

Extending A should make clone() available to B also ? If that is, so values of i and j should be copied to l and m also ? Is this possible ?

like image 230
nr5 Avatar asked Sep 22 '12 07:09

nr5


People also ask

Why is clone method protected in Java?

It is protected because the default implementation does a shallow memberwise copy of all fields (including private), circumventing constructor.

Can we override clone method in Java?

From Java 1.5 onwards an overriding method can return subclass of return type declared in original method, which means you can return sub class from clone method. It is known as co-variant method overriding.

Which is the correct way to implement clone method?

Creating a copy using the clone() method The class whose object's copy is to be made must have a public clone method in it or in one of its parent class. Every class that implements clone() should call super. clone() to obtain the cloned object reference. The class must also implement java.

How does clone () work in Java?

clone() method acts like a copy constructor. It creates and returns a copy of the object. Since the Object class has the clone method (protected) you cannot use it in all your classes. The class which you want to be cloned should implement clone method and overwrite it.


2 Answers

clone() is protected method and to make accessible in sub-classes, override it with public access.

class A implements Cloneable{
    .....
    @Override
    public Object clone() throws CloneNotSupportedException{
      return super.clone();
    }
}
like image 174
KV Prajapati Avatar answered Oct 17 '22 11:10

KV Prajapati


From Javadoc of Cloneable

By convention, classes that implement this interface should override Object.clone (which is protected) with a public method. See Object.clone() for details on overriding this method.

Note that this interface does not contain the clone method. Therefore, it is not possible to clone an object merely by virtue of the fact that it implements this interface. Even if the clone method is invoked reflectively, there is no guarantee that it will succeed.

Clone is one of the early designs in java and it has flaws

About access- When a method is protected, it can only be accessed by the class itself, subclasses of the class, or classes in the same package as the class.

So it is accessible in Aand B classes the way you are doing it is only possible if you are in the same package that happens to be java.lang

You can provide some method like this inside A.

public A copy() throws CloneNotSupportedException {
        return (A) clone();
    }

Correct Implementation

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

Also Remember parent is not type of child so casting from A to B will not work. Child is type of Parent so casting from B to A will work.

like image 42
Amit Deshpande Avatar answered Oct 17 '22 09:10

Amit Deshpande