Pergunta

I am trying to clone a object of class Integer, which does implement the cloneable inteface.

Integer a = new Integer(4);  
Integer b = a.clone();

I know there are work arounds for this, but I must implement it like this. why I am getting this error = clone() has protected access in java.lang.Object

Why would it say this? Isn't the clone method a public abstract method of clonable interface, what does it have to do with object. Thanks in advance :-)

Foi útil?

Solução

Sure, all methods in Object are inherited. The clone method however is protected, thus only accessible from within subclasses.

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.

The reason why you can call clone() in most other circumstances is that the subclass "opens it up" by overriding it with the public access modifier.

Outras dicas

java.lang.Integers are immutable. There is no reason to clone one. If you're trying to waste memory, try Integer.valueOf(myInteger.intValue()).

The error comes because clone method of java.lang.Object is not visible publicly.

As Amit and aioobe points out, Integer is immutable, so no need to clone it.

But to answer your question. The clone() method is not part of the the clonable interface see: http://download.oracle.com/javase/6/docs/api/java/lang/Cloneable.html as aioobe tells you.

The clone method is declared as protected in Object, and you must overwrite it with a public method in order to use it. See http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#clone()

In short the reason for this is, that in order to clone a object, it might or might not be necessary to do a "deep-clone" eg. clone fields and their sub elements. Or it might not make sense to clone an object, as the case is with Integer (because it's immutable)

First of all obtaining a copy through cloning i needed when you dont want others to change your copy. Now Integer is a wrapper class like String and Double that are Immutable. That means you cant change the internals of it. So as long as you have the original reference your object is intact.

say

Integer a = new Integer(4); // a referencing to this newly Created Integer
    b = a;  // b is referencing to..
    b = new Integer(8) // b no longer references to 4. 
                      //We changed the reference not the internals of it which is impossible.

It may be hard to believe but your error is right : clone() has protected access in java.lang.Object

Yes, because the clone() method is protected it can be only inherited, but you can't call it on object of another class. Every class inherit Object, so you can just call clone().

But in (default/native) clone() method you have an if(){} in which if your class not implements Cloneable, it will throw an Exception CloneNotSupportedException. I said native because, the clone() method is native, when you call it, in back is called another method writed in C++.

Here is a small part of the code which is called when you call clone().

if (!klass->is_cloneable()) {
    ResourceMark rm(THREAD);
    THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
  }

thanks Is it possible to find the source for a Java native method?

you can use reflection to call the clone method without override it in your object.

public class Main{
    public static void main(String[] args) throws CloneNotSupportedException {
        A a = new A();
        Object o = new Object();
        Method method = null;
        try {
            method = o.getClass().getDeclaredMethod("clone");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        method.setAccessible(true);
        try {
            System.out.println(method.invoke(a));
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

class A implements Cloneable {
}

and method.invoke(a) instanceof A is evaluated as true

without implementing Cloneable you will get

Caused by: java.lang.CloneNotSupportedException: defaultPackage.A
    at java.lang.Object.clone(Native Method)

And because Integer don't implements Cloneable, the clone() method will throw java.lang.CloneNotSupportedException.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top