繁体   English   中英

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

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

我尝试了以下代码来克隆对象。 编译时显示克隆受保护且无法访问,但我有扩展的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();

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

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


(回到你的问题)对象本身不可复制(不实现Cloneable),因此无法克隆。 并且因为Object#clone作为受保护的方法中,任何亚类实现Object (=事实上每一个类)可以访问其继承的clone()的“内部的java.lang方法和每类package can access克隆()从其它`方法对象也是。

为了快速了解修饰符,请看这个漂亮的矩阵

你绝对必须使用clone吗? 大多数人都认为Java的clone是破碎的。

设计中的Josh Bloch - 复制构造函数与克隆

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

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

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

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

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

相关问题


那么如何复制对象呢?

这是本书的引用:

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

在这种情况下,可以通过提供另一个StoreDateStoreDate构造函数或提供static StoreDate newInstanceFrom(StoreDate other)的实用程序方法来实现它。

相关问题

这里的关键是类属于哪个包。

这在JLS第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包即可解决问题。

也就是说,这确实编译:

文件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 )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM