开发者

Accessing clone() from java.lang.Object

开发者 https://www.devze.com 2023-02-13 03:22 出处:网络
Here is something that I cannot understand. In java.lang.Object the clone() is defined with protected modifier. By definition than it can be accessed by name inside its own class definition, by name

Here is something that I cannot understand.

In java.lang.Object the clone() is defined with protected modifier. By definition than it can be accessed by name inside its own class definition, by name inside any class derived from it, and by name in the definition of any class in the same package.

Here the Sample class is in another package, and obviously it can't access clone() from the Object class. But as Sample derives implicitly from Objec开发者_C百科t, why is it not able to access it? The definition doesn't say that it HAS to satisfy both conditions (inside same package AND also to be a subclass).

public class Sample {

  public Object foo() throws CloneNotSupportedException {
   ... 
   return someObject.clone();
  }
}


In your case, the clone() method is not visible because you are not calling it from a subclass. Sample derives from Object, so it can access its own clone() method, but not that of other objects.

Object clone() was designed with several mistakes. So it is not a good practice to use it - it is very hard to get it right:

  • the assumption is that not every object is clonable by default
  • if you override clone() making it public, it will still fail, because each class has to implement Cloneable
  • Cloneable, however, does not define any methods, so the users of the objects can't refer to it as Cloneable and expect a clone method.
  • every class in a hierarchy must call super.clone() for the default cloning mechanism to work

Check this question for alternatives.


Works for me: http://ideone.com/eST8Y

import java.util.*;
import java.lang.*;

class Main
{
    public Object foo() throws CloneNotSupportedException
    {
        return this.clone();
    }
    
    public static void main (String[] args) throws java.lang.Exception
    {
        new Main().foo();
    }
}

This compiles without error. It still throws a runtime CloneNotSupportedException because Main does not implement Cloneable.

A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class.

Invoking Object's clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown.


@Bozho's answer is really the right answer here, though. Just don't use Object.clone().

See Effective Java, Item 10: Override clone judiciously (Item 11 in later editions).


The class type of someObject is important here. Object someObject might not be overriding the clone() method of Object class, thus making is invisible to class Sample.


What do you mean "not able to access it"? Do you mean it won't compile or do you mean it throws the CloneNotSupportedException.

Object.clone() will throw CloneNotSupportedException if your class doesn't implement the Cloneable interface.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号