亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在Java中實現單例模式的有效方法是什么?

在Java中實現單例模式的有效方法是什么?

元芳怎么了 2019-05-22 15:22:09
在Java中實現單例模式的有效方法是什么?在Java中實現單例模式的有效方法是什么?
查看完整描述

5 回答

?
ITMISS

TA貢獻1871條經驗 獲得超8個贊

根據用途,有幾個“正確”的答案。

從java5開始,最好的方法是使用枚舉:

public enum Foo {
   INSTANCE;}

前java5,最簡單的情況是:

public final class Foo {

    private static final Foo INSTANCE = new Foo();

    private Foo() {
        if (INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return INSTANCE;
    }

    public Object clone() throws CloneNotSupportedException{
        throw new CloneNotSupportedException("Cannot clone instance of this class");
    }}

我們來看看代碼吧。首先,你希望課程是最終的。在這種情況下,我使用了final關鍵字讓用戶知道它是最終的。然后,您需要將構造函數設置為私有,以防止用戶創建自己的Foo。從構造函數中拋出異常會阻止用戶使用反射來創建第二個Foo。然后創建一個private static final Foo字段來保存唯一的實例,并創建一個public static Foo getInstance()返回它的方法。Java規范確保僅在首次使用類時調用構造函數。

當你有一個非常大的對象或繁重的構造代碼并且還有其他可訪問的靜態方法或字段可能在需要實例之前使用時,那么你只需要使用延遲初始化。

您可以使用a private static class來加載實例。然后代碼看起來像:

public final class Foo {

    private static class FooLoader {
        private static final Foo INSTANCE = new Foo();
    }

    private Foo() {
        if (FooLoader.INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return FooLoader.INSTANCE;
    }}

由于該行private static final Foo INSTANCE = new Foo();僅在實際使用類FooLoader時執行,因此它負責延遲實例化,并且保證是線程安全的。

當您還希望能夠序列化對象時,需要確保反序列化不會創建副本。

public final class Foo implements Serializable {

    private static final long serialVersionUID = 1L;

    private static class FooLoader {
        private static final Foo INSTANCE = new Foo();
    }

    private Foo() {
        if (FooLoader.INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return FooLoader.INSTANCE;
    }

    @SuppressWarnings("unused")
    private Foo readResolve() {
        return FooLoader.INSTANCE;
    }}

該方法readResolve()將確保將返回唯一的實例,即使該對象在上一次運行的程序中被序列化也是如此。


查看完整回答
反對 回復 2019-05-22
  • 5 回答
  • 0 關注
  • 863 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號