真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

徹底搞懂防止破壞單例類模式-創(chuàng)新互聯(lián)

在優(yōu)銳課的學(xué)習(xí)分享中,我們探討了破壞單例屬性的三種主要方法以及如何防止它。分享給大家參考學(xué)習(xí)。

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站建設(shè)、網(wǎng)站制作與策劃設(shè)計(jì),裕華網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:裕華等地區(qū)。裕華做網(wǎng)站價(jià)格咨詢:18982081108

我們習(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è)對象。 考慮以下示例:
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é)流的對象保存到文件中或通過網(wǎng)絡(luò)發(fā)送。 假設(shè)你先序列化Singleton類,然后再次對該對象反序列化,它將創(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)建原始對象的副本; 如果我們在單例模式中應(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();
    }

然后,測試克隆以打破單例。

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的克隆對象,它將拋出異常,如以下代碼所示。

@Override
    protected Object clone() throws CloneNotSupportedException  {
        throw new CloneNotSupportedException();
    }

現(xiàn)在,我們可以運(yùn)行l(wèi)oningSingleton類; 在創(chuàng)建單個(gè)對象的克隆對象時(shí),它將拋出CloneNotSupportedException。

文章寫到這里,如有不足之處,歡迎補(bǔ)充評論.希望這篇文章對你有用!

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。


分享標(biāo)題:徹底搞懂防止破壞單例類模式-創(chuàng)新互聯(lián)
文章地址:http://weahome.cn/article/jpghg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部