3 回答

TA貢獻(xiàn)1815條經(jīng)驗(yàn) 獲得超13個(gè)贊
在您Cloneable按單例實(shí)現(xiàn)之前,它不會發(fā)生(這是一種反模式,因?yàn)樗c單例的實(shí)際目的相矛盾)。因此,只有當(dāng)您執(zhí)行以下操作時(shí),它才會發(fā)生:
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
即使這樣在這種情況下,你可以通過重寫解決這個(gè)問題,clone在Singleton和拋出異常。

TA貢獻(xiàn)1809條經(jīng)驗(yàn) 獲得超8個(gè)贊
Java文檔說到Object.clone()
:
創(chuàng)建并返回此對象的副本?!皬?fù)制”的確切含義可能取決于對象的類別。
這取決于您對clone()
方法的實(shí)現(xiàn),您將獲得哪種復(fù)制或克隆。但是Java-Doc進(jìn)一步說:
按照慣例,此方法返回的對象應(yīng)獨(dú)立于該對象(將被克?。?/p>
按照這個(gè)約定,克隆將是以前是單例實(shí)例的另一個(gè)獨(dú)立實(shí)例。
繼續(xù)使用Java-Doc:
Object類本身并不實(shí)現(xiàn)Cloneable接口,因此在對象為Object的對象上調(diào)用clone方法將導(dǎo)致在運(yùn)行時(shí)引發(fā)異常。
因此,您必須顯式聲明您的類implements Cloneable
。只要您不這樣做,clone()
實(shí)例上就不會有任何公共方法。但是您不會為單例執(zhí)行此操作,因?yàn)檫@會使您的類設(shè)計(jì)(單例)無用。
如果您沒有聲明單例類final
,而是將其擴(kuò)展為另一個(gè)類(實(shí)例的實(shí)例將調(diào)用super.clone()
此類),則會拋出CloneNotSupportedException
。
如果您根據(jù)Java-Doc明確聲明您的單例類implements Cloneable
,則:
創(chuàng)建該對象類的新實(shí)例,并使用該對象相應(yīng)字段的內(nèi)容完全初始化其所有字段,就像通過賦值一樣;字段的內(nèi)容本身不會被克隆。因此,此方法執(zhí)行此對象的“淺復(fù)制”,而不是“深復(fù)制”操作。
要獲得適當(dāng)?shù)目寺?,Java-Doc會Cloneable
說:
...實(shí)現(xiàn)此接口的類應(yīng)重寫Object.clone ...因此,僅憑其實(shí)現(xiàn)此接口的事實(shí)就不可能克隆對象。
因此,您確實(shí)必須明確地做到這一點(diǎn)。
回答問題:
可能嗎?是的-是,但前提是您允許。
有意嗎 不。
還要注意:
除了上述通過使用反射的方法,您還可以嘗試?yán)@過單例類的可見性限制來創(chuàng)建更多實(shí)例。
添加回答
舉報(bào)