7

シングルトン設計パターンを実装する標準的な方法は次のとおりです。

public class Singleton {
    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }

    private Singleton() {}
}

次のように実装することもできるかどうか疑問に思っていました。

public class Singleton {
    private Singleton() {}
    public final static Singleton INSTANCE = new Singleton();
}

はいの場合、どのバージョンが優れていますか?

4

4 に答える 4

10

ない。どちらの場合も、信頼できるコンシューマーはリフレクションを介してプライベート コンストラクターを呼び出すことができます。追加の問題は、これらの実装は、シリアライゼーションを行うために追加の手順を実行しない限りSingleton、うまく動作しないことです (デフォルトでは、単純なアプローチを採用すると、 aがデシリアライズされるたびに、新しいインスタンスが作成されます)

正しい解決策はenum、単一の値を定義する を使用することです。

public enum Singleton {
    INSTANCE;

    // methods
}

効果的な Java から:

このアプローチはまだ広く採用されていませんが、単一要素の列挙型がシングルトンを実装する最良の方法です。

于 2013-08-13T04:58:00.327 に答える
1

シングルトンの実現に列挙型を使用しないのはなぜですか?

 public enum SingletonEnum {
     Instance;
     private static String testStr = "";

     public static void setTestStr(String newTestStr) {
         testStr = newTestStr;
     }

     public static String getTestStr() {
         return testStr;
     }

     public static String sayHello(String name) {
         return "Hello " + name;
     }
 }
于 2013-08-13T04:59:40.690 に答える
0

私の意見では、オブジェクト指向のアプローチにより整合しているように見えるので、最初のものの方が優れています。

于 2013-08-13T04:56:27.980 に答える
0

どちらのソリューションにも特に問題はありませんが、ウィキペディアからのこのソリューションは、最高の互換性を提供し、スレッドセーフなシングルトンを提供するはずです。

メリーランド大学のコンピューター サイエンス研究者 Bil​​l Pugh は、Java で実装された場合のシングルトン パターンの根底にあるコードの問題について書いています[11]。「ダブルチェック ロック」イディオムに関する Pugh の取り組みは、Java 5 の Java メモリ モデルの変更と、Java でシングルトンを実装するための標準的な方法と一般に見なされているものにつながりました。初期化オンデマンド ホルダー イディオムとして知られる手法は、可能な限り怠惰であり、既知のすべてのバージョンの Java で機能します。クラスの初期化に関する言語保証を利用するため、すべての Java 準拠のコンパイラと仮想マシンで正しく動作します。ネストされたクラスは、getInstance() が呼び出された時点よりも早く参照されません (したがって、クラス ローダーによって以前にロードされません)。したがって、

public class Singleton {
        // Private constructor prevents instantiation from other classes
        private Singleton() { }

        /**
        * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
        * or the first access to SingletonHolder.INSTANCE, not before.
        */
        private static class SingletonHolder { 
                public static final Singleton INSTANCE = new Singleton();
        }

        public static Singleton getInstance() {
                return SingletonHolder.INSTANCE;
        }
}
于 2013-08-13T04:57:14.157 に答える