开发者

Explicitly extending Object class and calling clone method of object throwing error

i tried the following code for cloning the object. while compiling it shows clone is protected and cannot be accessed, but i had extended开发者_开发技巧 Object class, hence the clone method will be public to my class . please explain me the reason.

class storeDate extends Object {

  public static void main(String[] args)
  {

    storeDate d = new storeDate();
    Object o = (storeDate)d;
    o.clone():
  }

}

while compilation i get this error

clone() has protected access in java.lang.Object kkk.clone();


The key thing here is which package the classes belongs to.

This is explained in JLS paragraph 6.6.2:

6.6.2 Details on protected Access
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.


Examples:

This does not compile:

FILE pkg1/A.java (corresponds to the Object class in your question)

package pkg1;
public class A {
    protected void method() {};
}

FILE pkg2/B.java (corresponds to storeDate in your question)

package pkg2;
import pkg1.A;
public class B extends A {
    public static void main(String args[]) {
        new A().method();
    }
}

javac outputs the following:

pkg2/B.java:5: method() has protected access in pkg1.A
        new A().method();
               ^

(which is similar to what you have: clone() has protected access in java.lang.Object kkk.clone();)


Simply moving B to the pkg1 package solves it.

That is, this does compile:

FILE pkg1/A.java (unchanged)

package pkg1;
public class A {
    protected void method() {};
}

FILE pkg1/B.java (moved from pkg2 to pkg1)

package pkg1;                 // Changed from pkg2
//import pkg1.A;              // Not necessary anymore.
public class B extends A {
    public static void main(String args[]) {
        new A().method();
    }
}

So, what would have been required for you to be able to do something like new Object().clone()? Well, you would have to belong to the java.lang package (which in turn, however results in a SecurityException: Prohibited package name: java.lang).


Do you absolutely have to use clone? Most people agree that Java's clone is broken.

Josh Bloch on Design - Copy Constructor versus Cloning

If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken. [...] It's a shame that Cloneable is broken, but it happens.

You may read more discussion on the topic in his book Effective Java 2nd Edition, Item 11: Override clone judiciously. He recommends instead to use a copy constructor or copy factory.

He went on to write pages of pages on how, if you feel you must, you should implement clone. But he closed with this:

Is all this complexities really necessary? Rarely. If you extend a class that implements Cloneable, you have little choice but to implement a well-behaved clone method. Otherwise, you are better off providing alternative means of object copying, or simply not providing the capability.

The emphasis was his, not mine. The entire item is a must read to understand the issues deeper and to consider alternatives.

Related questions

  • Why is the clone() method protected in java.lang.Object?
  • Why people are so afraid of using clone() (on collection and JDK classes) ?
  • How to properly override clone method?

So how to copy objects?

Here's a quote from the book:

A fine approach to object copying is to provide a copy constructor or copy factory.

In this case, it can be implemented simply with providing a StoreDate constructor that takes another StoreDate, or providing a utility method static StoreDate newInstanceFrom(StoreDate other).

Related questions

  • clone() vs copy constructor vs factory method??


You should override and implement the clone method from Object. Then you can call clone() or super.clone() if you need the method body from Object.clone. The standard implementation just clones primitive types and references to other objects.

And the subclass needs to implement the interface Cloneable (which is just a marker interface with no methods to implement).


(Back to your question) Object itself is not cloneable (doesn't implement Cloneable) and thus can't be cloned. And because Object#clone is implemented as a protected method, any subclass of Object (= every class in fact) can access its inherited clone() method and every class inside the 'java.langpackage can accessclone()` methods from other objects too.

For a quick understanding of modifiers see this nice matrix.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜