中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

徹底搞懂防止破壞單例類模式

在優(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)

成都網(wǎng)站建設(shè)公司
阿克陶县| 盐亭县| 葵青区| 马尔康县| 连平县| 惠来县| 北辰区| 景洪市| 浦江县| 绥棱县| 沂水县| 永顺县| 梨树县| 论坛| 巍山| 新巴尔虎右旗| 梁河县| 图们市| 从化市| 铜鼓县| 乌鲁木齐县| 大余县| 巴青县| 泰顺县| 柘荣县| 阿拉善盟| 呼伦贝尔市| 汉寿县| 卫辉市| 邳州市| 南雄市| 孝昌县| 凭祥市| 扎兰屯市| 伊宁市| 城步| 娄烦县| 巴马| 朝阳市| 玛曲县| 环江|