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.
    }
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
sekhar
  • 710
  • 1
  • 7
  • 13

8 Answers8

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

EsotericMe
  • 811
  • 1
  • 5
  • 11
  • 6
    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? – Justin Oct 04 '12 at 14:19
  • 5
    @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. – Karthik Bose Dec 17 '13 at 11:05
  • @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? – S Kumar Feb 10 '18 at 19:42
  • @KarthikBose So, from the [link](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) 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. – S Kumar Feb 10 '18 at 19:48
  • 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 getting – Manash Ranjan Dakua Feb 05 '19 at 10:58
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

Prashant K
  • 144
  • 1
  • 4
3

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

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

Suraj Chandran
  • 24,433
  • 12
  • 63
  • 94
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.

zx485
  • 28,498
  • 28
  • 50
  • 59
spirit
  • 21
  • 1
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

prime
  • 14,464
  • 14
  • 99
  • 131
0

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

Swagatika
  • 3,376
  • 6
  • 30
  • 39
  • 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. – Stephen C Oct 01 '21 at 12:30
-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.

FocalPoint
  • 15
  • 4
  • 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. – Vikas Verma Mar 16 '17 at 08:03
-1

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

Yanki Twizzy
  • 7,771
  • 8
  • 41
  • 68
  • 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. – Stephen C Oct 01 '21 at 12:25