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
  • props不一定是static
  • 构造函数会自动且急切地为您调用

注意最后一点。由于enum-singleton 是在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() {

    }
}

一个很好的例子是 Planet 枚举:http ://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

于 2012-10-02T20:35:41.397 回答
1
public enum BitCheck {

    INSTANCE;

    private BitCheck() {
        // initialize here
    }

}
于 2012-10-02T20:36:04.110 回答
1

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

private Map<...> props;

您可以查看在 Java 中使用 Enum 作为单例的最佳方法是什么?这与您想要的相似。

于 2012-10-02T20:38:45.623 回答
0

您可以在基于 Enum 的单例代码中尝试类似的操作。这将确保 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;
   }
}

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

于 2016-06-20T11:19:19.237 回答