20

オブジェクトを使用する前に初期化する必要がある場合、Java 列挙型ベースのシングルトンを初期化する適切な方法は何ですか。

コードを書き始めましたが、正しく実行できているかどうかわかりません。このシングルトンを正しく実装するのを手伝ってもらえますか?

public enum BitCheck {

    INSTANCE;

    private static HashMap<String, String> props = null;

    public synchronized void  initialize(HashMap<String, String> properties) {
        if(props == null) {
            props = properties;
        }
    }

    public boolean isAenabled(){
        return "Y".equalsIgnoreCase(props.get("A_ENABLED"));
    }

    public boolean isBenabled(){
        return "Y".equalsIgnoreCase(props.get("B_ENABLED"));
    }

}
4

6 に答える 6

36

のコンストラクターを作成することは完全に可能ですenum:

public enum BitCheck {

    INSTANCE;

    BitCheck() {
        props = new HashMap<String, String>();
    }

    private final Map<String, String> props;

    //..

}

ご了承ください:

  • propsフィールドは final にすることができます (私たちは好きですfinal)
  • propsである必要はありませんstatic
  • コンストラクターは自動的に熱心に呼び出されます

最後の点に注意してください。-singletonenumはクラスがロードされるときに熱心に作成されるenum BitCheckため、コンストラクターに引数を渡す方法はありません。もちろん、INSTANCE宣言を通じてできます:

public enum BitCheck {

    INSTANCE(new HashMap<String, String>());

    BitCheck(final Map<String, String> props) {
        this.props = props;
    }

しかし、これは何の違いもありませんよね?何を達成したいですか?たぶん、遅延初期化されたシングルトンが実際に必要ですか?

于 2012-10-02T20:34:26.340 に答える
6

宣言で初期化する必要があります。

public enum BitCheck {
    INSTANCE;
    private final Map<String, String> props = new ConcurrentHashMap<String, String>();

    public void putAll(HashMap<String, String> map) {
        props.putAll(map);
    }
}
于 2012-10-02T20:39:40.507 に答える
2

次のようなコンストラクターを定義する必要があります。

public enum BitCheck {

    INSTANCE;
    private final HashMap<String, String> props;

    BitCheck() {

    }
}

非常に良い例は、次の惑星列挙型です:http: //docs.oracle.com/javase/tutorial/java/javaOO/enum.html

于 2012-10-02T20:35:41.397 に答える
1

インターフェイスに実装する必要があるため、次のように変更する必要があります。

private Map<...> props;

Javaで列挙型をシングルトンとして使用するための最良のアプローチは何ですか?これはあなたが望むものに似ています。

于 2012-10-02T20:38:45.623 に答える
1
public enum BitCheck {

    INSTANCE;

    private BitCheck() {
        // initialize here
    }

}
于 2012-10-02T20:36:04.110 に答える
0

Enum ベースのシングルトン コード内でこのようなことを試すことができます。これにより、Singleton を 1 回だけ初期化できるようになります。

private static Properties props;
private static AtomicBoolean isInitialized = new AtomicBoolean(false);

public void init(Properties props){
   if(isInitialized.compareAndSet(false, true)) {
       this.props = props;
   }
}

注: より複雑な初期化の場合、initStarted と initCompleted に 2 つの AtomicBoolean が必要になります (単一の AtomicBoolean - isInitialized ではなく)。次に、最初のスレッドが initStarted を設定し、初期化手順を実行します。残りは、最初のスレッドによって initCompleted が true に設定されるまで待機します。

于 2016-06-20T11:19:19.237 に答える