显式扩展Object类并调用对象抛出错误的clone方法

时间:2010-06-10 07:02:33

标签: java

我尝试使用以下代码来克隆对象。编译时显示克隆受保护且无法访问,但我有扩展的Object类,因此克隆方法将公开给我的类。请解释原因。

class storeDate extends Object {

  public static void main(String[] args)
  {

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

}

编译时我收到此错误

clone()在java.lang.Object中具有受保护的访问权限         kkk.clone();

3 个答案:

答案 0 :(得分:1)

您应该从Object覆盖并实现clone方法。然后,如果您需要clone()中的方法正文,则可以致电super.clone()Object.clone。标准实现只是克隆了原始类型和对其他对象的引用。

子类需要实现接口Cloneable(它只是一个没有方法可以实现的标记接口)。


(回到你的问题)对象本身不可克隆(不实现Cloneable),因此无法克隆。并且因为Object#clone被实现为受保护的方法,所以Object的任何子类(实际上=每个类)都可以访问其继承的clone()方法以及'java.lang {{中的每个类。 1}} clone()`来自其他对象的方法。

要快速了解修饰符,请参阅此nice matrix

答案 1 :(得分:1)

你绝对必须使用clone吗?大多数人都同意Java clone已被破坏。

Josh Bloch on Design - Copy Constructor versus Cloning

  

如果您已经阅读了我的书中有关克隆的内容,特别是如果您在这些内容之间进行了阅读,您会发现我认为clone已经被彻底打破了。 [...] Cloneable被打破是一种耻辱,但它确实发生了。

您可以在他的书 Effective Java 2nd Edition,Item 11:明智地覆盖clone 中阅读有关该主题的更多讨论。他建议改为使用复制构造函数或复制工厂。

他接着写了一些页面,说明如果你认为必须如何,你应该实施clone。但他以此结束了:

  

所有这些复杂性真的有必要吗?很少。如果扩展实现Cloneable的类,除了实现行为良好的clone方法之外别无选择。否则,您最好提供替代的对象复制方法,或者根本不提供该功能

重点是他,而不是我的。必须阅读整个项目以更深入地了解问题并考虑替代方案。

相关问题


那么如何复制对象?

以下是本书的引用:

  

对象复制的一个很好的方法是提供复制构造函数或复制工厂

在这种情况下,可以通过提供另一个StoreDate的{​​{1}}构造函数或提供实用程序方法StoreDate来实现它。

相关问题

答案 2 :(得分:1)

关键是这些类属于哪个包。

JLS paragraph 6.6.2中解释了这一点:

  

6.6.2有关受保护访问的详细信息
  对象的受保护成员或构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明


示例:

无法编译

FILE pkg1 / A.java (对应于您问题中的Object类)

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

FILE pkg2 / B.java (对应于你问题中的storeDate)

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

javac输出以下内容:

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

(类似于你所拥有的: clone()在java.lang.Object中具有受保护的访问权限kkk.clone();


只需将B移至pkg1包即可解决问题。

也就是说,编译:

FILE pkg1 / A.java (未更改)

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

FILE pkg1 / B.java (从pkg2移到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();
    }
}

那么,您需要做什么才能做new Object().clone()之类的事情?好吧,你必须属于java.lang包(反过来会导致SecurityException: Prohibited package name: java.lang)。