The method clone() from object is not visible?
Asked Answered
A

8

50

Question:

package GoodQuestions;
public class MyClass {  
    MyClass() throws CloneNotSupportedException {
        try {
            throw new CloneNotSupportedException();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }   

    public static void main(String[] args) {    
        try {
            MyClass  obj = new MyClass();
            MyClass obj3 = (MyClass)obj.clone();            
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

Here class 'MyClass' can able to clone its own object by calling the clone method in 'Object' class. When I try to clone the of this class('MyClass') in another class('TestSingleTon') in the same package 'GoodQuestions' it is throwing the following compile time error.

'The method clone() from the type Object is not visible'

So here is the code it throwing the above error?

package GoodQuestions;
public class TestSingleTon {
    public static void main(String[] args) {
        MyClass  obj = new MyClass();
        MyClass obj3 = obj.clone(); ---> here is the compile error.
    }
}
Austronesia answered 25/2, 2011 at 10:46 Comment(0)
P
12

This error occurs because in Object class clone() method is protected. So you have to override clone() method in respective class. Eg. Add below code in MyClass

@Override
protected Object clone() throws CloneNotSupportedException {

    return super.clone();
}

Also implement Cloneable interface. Eg. public class MyClass implements Cloneable

Perusse answered 28/7, 2016 at 9:12 Comment(1)
be careful return super.clone() may not be enoughYapok
C
49

clone() has protected access. Add this in MyClass

public Object clone(){  
    try{  
        return super.clone();  
    }catch(Exception e){ 
        return null; 
    }
}

Also Change to public class MyClass implements Cloneable

Copperas answered 25/2, 2011 at 10:59 Comment(5)
I assumed the protected modifier meant package-level as well as subclass. Isn't every Class in Java a subclass of Object? Your answer is right so what have I misunderstood here?Decrease
@Justin: Yes it meant package-level as well as subclass. So inside your subclass "MyClass", it'll be visible. But it won't be visible to "TestSingleTon", which is neither same package nor subclass.Hampstead
@KarthikBose So, that means that protected methods can be called in the subclasses by the same subclass object. In any subclass, we cannot call it with some other subclass object like in this case clone() is called by MyClass object in the TestSingleton?Lumpfish
@KarthikBose So, from the link stating "The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package." needs more clarification stating that.Lumpfish
In an class if I create inside main Object o = new Object(); o.clone(); if i override also clone() in my class then clone() is not visable i am gettingHelfand
P
12

This error occurs because in Object class clone() method is protected. So you have to override clone() method in respective class. Eg. Add below code in MyClass

@Override
protected Object clone() throws CloneNotSupportedException {

    return super.clone();
}

Also implement Cloneable interface. Eg. public class MyClass implements Cloneable

Perusse answered 28/7, 2016 at 9:12 Comment(1)
be careful return super.clone() may not be enoughYapok
P
3

Because clone() is a protected method. See Object.clone() for details.

Override clone() in MyClass and make the class implement Cloneable interface.

Parous answered 25/2, 2011 at 10:54 Comment(0)
R
2

The subtlety is that the clone() method of MyClass is inherited, not defined in MyClass. So MyClass can invoke clone() of the Object because it is protected, but MyClass doesn't really have a clone() of itself, so TestSingleTon can't access clone() of MyClass because there is no clone() method. Although they are both in a same package, you need to define a clone() method in MyClass to assure it really "has" the clone(). By the way, don't forget to implement the interface Cloneable for MyClass.

Rosaliarosalie answered 25/6, 2016 at 16:11 Comment(0)
G
1

Object.clone() method has protected access, meaning it's visible to sub-classes and classes in the same package.

It's good to have a copy constructor for manually copying the object.

/**
    Deep copy all the information from other to this
*/
public MyClass (MyClass  other) {
     this.id = other.id;
}

READ Why a copy constructor from Josh Bloch

Gayden answered 11/6, 2018 at 13:1 Comment(0)
L
0

You just have to make MyClass implement Cloneable interface. No need to provode implementation for clone().

Lavender answered 14/5, 2011 at 12:42 Comment(1)
The question is not about Cloneable, and if you want clone() to be a public method (which is what the question is about in effect), you do have to provide your own implementation.Damek
Z
-1

For you to be able to clone MyClass, it has to implement the Cloneable interface

Zildjian answered 25/2, 2011 at 10:54 Comment(1)
This doesn't answer the question. The example in the question is already implementing Cloneable. It is asking about a compilation error that is due to clone() being a protected method.Damek
M
-1

I did some test code on this and here are my findings:

When a protected member is inherited across package it becomes private member of inherited class

whereas

when a protected member is inherited within the same package it becomes default member of inherited class.

In your example, clone() from Object class is inherited into MyClass across package. Object class is in java.lang package and MyClass is in GoodQuestions package. So clone() method becomes a private member of MyClass class.

That explains why you are unable to access clone() method from TestSingleTon class.

Maggot answered 23/2, 2013 at 4:32 Comment(1)
I don't think your theory is correct. I have done the following things:- 1) Created class called Parent with protected method called callProtected() 2) Created another class in different package called Person that extends Parent class 3) Created another class in the same package of Person class called Student that extends Person So, according to your theory if protected members in different package become private then I shouldn't able to access callProtected method in Student class but unfortunately, I could able to access callProtected method.Adorno

© 2022 - 2024 — McMap. All rights reserved.