在優(yōu)銳課的學(xué)習(xí)分享中,我們探討了破壞單例屬性的三種主要方法以及如何防止它。分享給大家參考學(xué)習(xí)。
成都創(chuàng)新互聯(lián)主要為客戶提供服務(wù)項(xiàng)目涵蓋了網(wǎng)頁視覺設(shè)計(jì)、VI標(biāo)志設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷推廣、網(wǎng)站程序開發(fā)、HTML5響應(yīng)式網(wǎng)站建設(shè)、成都手機(jī)網(wǎng)站制作、微商城、網(wǎng)站托管及網(wǎng)站建設(shè)維護(hù)、WEB系統(tǒng)開發(fā)、域名注冊(cè)、國(guó)內(nèi)外服務(wù)器租用、視頻、平面設(shè)計(jì)、SEO優(yōu)化排名。設(shè)計(jì)、前端、后端三個(gè)建站步驟的完善服務(wù)體系。一人跟蹤測(cè)試的建站服務(wù)標(biāo)準(zhǔn)。已經(jīng)為混凝土攪拌站行業(yè)客戶提供了網(wǎng)站開發(fā)服務(wù)。
我們習(xí)慣于在需要時(shí)在我們的應(yīng)用程序中使用單例設(shè)計(jì)模式。 眾所周知,在單例設(shè)計(jì)模式中,我們只能創(chuàng)建一個(gè)實(shí)例并在整個(gè)應(yīng)用程序中訪問它。 但是在某些情況下,它將破壞單例行為。
在三個(gè)主要概念中,我們可以打破Java中Singleton類的singleton屬性。 在這篇文章中,我們將討論如何破壞它以及如何防止它。
這是示例Singleton類和SingletonTest類。
單例.
Singleton.Java
package demo1;
public final class Singleton {
private static volatile Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
SingletonTest.java
package demo1;
public class SingletonTest {
public static void main(String[] args) {
Singleton object1 = Singleton.getInstance();
Singleton object2 = Singleton.getInstance();
System.out.println("Hashcode of Object 1 - " + object1.hashCode());
System.out.println("Hashcode of Object 2 - " + object2.hashCode());
}
}
這是輸出; 你可以看到它具有與objectOne和objectTwo相同的hashcode :
Hashcode of Object 1 - 1836019240
Hashcode of Object 2 - 1836019240
現(xiàn)在,我們將打破這種模式。 首先,我們將使用Java反射。
反射
Java Reflection是一種API,用于在運(yùn)行時(shí)檢查或修改方法,類和接口的行為。 使用Reflection API,我們可以在Singleton類中創(chuàng)建多個(gè)對(duì)象。 考慮以下示例:
ReflectionSingleton.java
package demo1;
import java.lang.reflect.Constructor;
public class ReflectionSingleton {
public static void main(String[] args) {
Singleton objOne = Singleton.getInstance();
Singleton objTwo = null;
try {
Constructor constructor = Singleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
objTwo = (Singleton) constructor.newInstance();
} catch (Exception ex) {
System.out.println(ex);
}
System.out.println("Hashcode of Object 1 - "+objOne.hashCode());
System.out.println("Hashcode of Object 2 - "+objTwo.hashCode());
}
}
這個(gè)例子展示了反射如何用Java反射來打破單例模式。 你將獲得兩個(gè)哈希碼,如下所示。 它在單例模式上有所突破。
防止單例模式反射
有很多方法可以防止反射API中的Singleton模式,但是最好的解決方案之一是,如果實(shí)例已經(jīng)存在,則在構(gòu)造函數(shù)中引發(fā)運(yùn)行時(shí)異常。 在這種情況下,我們無法創(chuàng)建第二個(gè)實(shí)例。
反序列化
在序列化中,我們可以將字節(jié)流的對(duì)象保存到文件中或通過網(wǎng)絡(luò)發(fā)送。 假設(shè)你先序列化Singleton類,然后再次對(duì)該對(duì)象反序列化,它將創(chuàng)建一個(gè)新實(shí)例,因此反序列化將破壞Singleton模式。
以下代碼用于說明單反模式如何隨反序列化而中斷。
為Singleton類實(shí)現(xiàn)Serializable接口。
DeserializationSingleton.Java
package demo1;
import java.io.*;
public class DeserializationSingleton {
public static void main(String[] args) throws Exception {
Singleton instanceOne = Singleton.getInstance();
ObjectOutput out = new ObjectOutputStream(new FileOutputStream("file.text"));
out.writeObject(instanceOne);
out.close();
ObjectInput in = new ObjectInputStream(new FileInputStream("file.text"));
Singleton instanceTwo = (Singleton) in.readObject();
in.close();
System.out.println("hashCode of instance 1 is - " + instanceOne.hashCode());
System.out.println("hashCode of instance 2 is - " + instanceTwo.hashCode());
}
}
輸出如下,你可以看到兩個(gè) hashcodes.
hashCode of instance 1 is - 2125039532
hashCode of instance 2 is - 381259350
防止單例模式反序列化
為了克服這個(gè)問題,我們需要覆蓋Singleton類中的readResolve()方法并返回相同的Singleton實(shí)例。 使用以下方法更新Singleton.java。
protected Object readResolve() {
return instance;
}
現(xiàn)在,運(yùn)行上面的DeserializationDemo類并查看輸出。
hashCode of instance 1 is - 2125039532
hashCode of instance 2 is - 2125039532
克隆
使用“克隆”方法,我們可以創(chuàng)建原始對(duì)象的副本; 如果我們?cè)趩卫J街袘?yīng)用克隆,這是同一回事。 它將創(chuàng)建兩個(gè)實(shí)例:一個(gè)實(shí)例和另一個(gè)實(shí)例。 在這種情況下,我們將打破Singleton原理,如下面的代碼所示。
實(shí)施「可克隆」介面,并在上述Singleton類別中覆寫clone方法
Singleton.java
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
然后,測(cè)試克隆以打破單例。
CloningSingleton.java
public class CloningSingleton {
public static void main(String[] args) throws CloneNotSupportedException, Exception {
Singleton instanceOne = Singleton.getInstance();
Singleton instanceTwo = (Singleton) instanceOne.clone();
System.out.println("hashCode of instance 1 - " + instanceOne.hashCode());
System.out.println("hashCode of instance 2 - " + instanceTwo.hashCode());
}
}
這是輸出:
hashCode of instance 1 - 1836019240
hashCode of instance 2 - 325040804
如果我們看到上面的輸出,則兩個(gè)實(shí)例具有不同的hashcodes。 這意味著這些實(shí)例不相同。
防止單例模式克隆
在上面的代碼中,它打破了Singleton原理,即。 e創(chuàng)建了兩個(gè)實(shí)例。 為了克服上述問題,我們需要實(shí)現(xiàn)/覆蓋clone()方法并從克隆方法中拋出異常CloneNotSupportedException。 如果有人嘗試創(chuàng)建Singleton的克隆對(duì)象,它將拋出異常,如以下代碼所示。
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
現(xiàn)在,我們可以運(yùn)行l(wèi)oningSingleton類; 在創(chuàng)建單個(gè)對(duì)象的克隆對(duì)象時(shí),它將拋出CloneNotSupportedException。
文章寫到這里,如有不足之處,歡迎補(bǔ)充評(píng)論.希望這篇文章對(duì)你有用!
本文題目:徹底搞懂防止破壞單例類模式
文章起源:http://www.rwnh.cn/article46/pgeceg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、軟件開發(fā)、面包屑導(dǎo)航、品牌網(wǎng)站建設(shè)、企業(yè)建站、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)