是否可以浅表复制单例类对象?

使用clone方法,我们能否获得已经做成单例的类的许多实例?

另外,有必要写“ implements Cloneable”,因为我了解到所有对象都是从Object类扩展的,因此在Object的另一个子对象上调用protected clone()的子对象应该没有访问问题


慕码人8056858
浏览 152回答 3
3回答

萧十郎

在您Cloneable按单例实现之前,它不会发生(这是一种反模式,因为它与单例的实际目的相矛盾)。因此,只有当您执行以下操作时,它才会发生:SomeClass.javaclass SomeClass implements Cloneable {    @Override    protected Object clone() throws CloneNotSupportedException {        return super.clone();    }}Singleton.javaclass Singleton extends SomeClass {    public static Singleton instance = new Singleton();    private Singleton() {}}Main.javaclass Main {    public static void main(String[] args) throws CloneNotSupportedException {        Singleton singleton1 = Singleton.instance;        Singleton singleton2 = singleton1.clone();        System.out.println("singleton1 : "                       + singleton1.hashCode());        System.out.println("singleton2 : "                       + singleton2.hashCode());     }}    输出单例1:445884362单例2:1793329556即使这样在这种情况下,你可以通过重写解决这个问题,clone在Singleton和抛出异常。

海绵宝宝撒

Java文档说到Object.clone():创建并返回此对象的副本。“复制”的确切含义可能取决于对象的类别。这取决于您对clone()方法的实现,您将获得哪种复制或克隆。但是Java-Doc进一步说:按照惯例,此方法返回的对象应独立于该对象(将被克隆)。按照这个约定,克隆将是以前是单例实例的另一个独立实例。继续使用Java-Doc:Object类本身并不实现Cloneable接口,因此在对象为Object的对象上调用clone方法将导致在运行时引发异常。因此,您必须显式声明您的类implements Cloneable。只要您不这样做,clone()实例上就不会有任何公共方法。但是您不会为单例执行此操作,因为这会使您的类设计(单例)无用。如果您没有声明单例类final,而是将其扩展为另一个类(实例的实例将调用super.clone()此类),则会抛出CloneNotSupportedException。如果您根据Java-Doc明确声明您的单例类implements Cloneable,则:创建该对象类的新实例,并使用该对象相应字段的内容完全初始化其所有字段,就像通过赋值一样;字段的内容本身不会被克隆。因此,此方法执行此对象的“浅复制”,而不是“深复制”操作。要获得适当的克隆,Java-Doc会Cloneable说:...实现此接口的类应重写Object.clone ...因此,仅凭其实现此接口的事实就不可能克隆对象。因此,您确实必须明确地做到这一点。回答问题:可能吗?是的-是,但前提是您允许。有意吗 不。还要注意:除了上述通过使用反射的方法,您还可以尝试绕过单例类的可见性限制来创建更多实例。

梵蒂冈之花

首先,切勿使用克隆。第二,克隆做浅拷贝。最后,建议将枚举用于单例,这是VM保证的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java