3 回答
TA贡献1815条经验 获得超13个赞
在您Cloneable按单例实现之前,它不会发生(这是一种反模式,因为它与单例的实际目的相矛盾)。因此,只有当您执行以下操作时,它才会发生:
SomeClass.java
class SomeClass implements Cloneable {
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Singleton.java
class Singleton extends SomeClass {
public static Singleton instance = new Singleton();
private Singleton() {}
}
Main.java
class 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和抛出异常。
TA贡献1809条经验 获得超8个赞
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 ...因此,仅凭其实现此接口的事实就不可能克隆对象。
因此,您确实必须明确地做到这一点。
回答问题:
可能吗?是的-是,但前提是您允许。
有意吗 不。
还要注意:
除了上述通过使用反射的方法,您还可以尝试绕过单例类的可见性限制来创建更多实例。
添加回答
举报