如何初始化基于Java枚举的Singleton?

时间:2012-10-02 20:25:29

标签: java enums singleton

如果我必须在使用该对象之前初始化它,那么初始化基于java enum的单例的正确方法是什么。

我已经开始编写代码,但我不确定我是否做得对。你能帮我实现这个单身对我来说是正确的吗?

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"));
    }

}

6 个答案:

答案 0 :(得分:31)

完全可以为enum

创建构造函数
public enum BitCheck {

    INSTANCE;

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

    private final Map<String, String> props;

    //..

}

请注意:

  • props字段可以是最终字段(我们喜欢final
  • props不一定是static
  • 构造函数会自动并且热切地为您调用

注意最后一点。由于enum - 在加载enum BitCheck类时急切地创建单例,因此无法将任何参数传递给构造函数。当然你可以通过INSTANCE声明:

public enum BitCheck {

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

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

但这没有任何区别,对吗?你想达到什么目的?也许你真的需要懒惰初始化的单身人士?

答案 1 :(得分:5)

您必须在声明中初始化它。

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

    public void putAll(HashMap<String, String> map) {
        props.putAll(map);
    }
}

答案 2 :(得分:2)

你需要定义一个这样的构造函数:

public enum BitCheck {

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

    BitCheck() {

    }
}

一个非常好的例子是Planet enum at:http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

答案 3 :(得分:1)

public enum BitCheck {

    INSTANCE;

    private BitCheck() {
        // initialize here
    }

}

答案 4 :(得分:1)

您应该实现接口,因此更改为:

private Map<...> props;

您可以查看与您想要的类似的What is the best approach for using an Enum as a singleton in Java?

答案 5 :(得分:0)

您可以在基于枚举的单例代码中尝试这样的操作。这将确保Singleton只能初始化一次。

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

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

注意:对于更复杂的初始化,您需要2个AtomicBooleans用于initStarted和initCompleted(而不是单个AtomicBoolean - isInitialized)。然后第一个线程设置initStarted并执行初始化步骤,其余的等待,直到第一个线程将initCompleted设置为true。