2012-10-02 28 views
14

什么是初始化基于java枚举的单例的正确方法,如果必须在使用该对象之前对它进行初始化。如何初始化基于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")); 
    } 

} 
+0

我不喜欢这个,你想达到什么目的? – zengr

+0

当你已经使用单例时,为什么只需要一个元素的枚举? – Dunes

+0

@Dunes我想要一个单例,这样我就可以在整个代码库中使用它来检查值。我将在启动过程中使用属性进行初始化,并将在整个项目中使用检查方法。 –

回答

30

这是完全有可能的enum创建构造函数:

public enum BitCheck { 

    INSTANCE; 

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

    private final Map<String, String> props; 

    //.. 

} 

需要注意的是:

  • props场可最终(我们喜欢final
  • props没有static
  • 构造函数被自动调用并且热切地为你调用

注意最后一点。由于加载enum BitCheck类时enum -singletons急切地创建,你有没有办法通过任何参数构造函数。当然你也可以通过INSTANCE声明:

public enum BitCheck { 

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

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

但是这并没有什么差别,对不对?你想实现什么?也许你真的需要懒惰初始化单身人士?

+0

我想这将是坏的想法创建像这样,因为构造函数不提供任何好处。它可以是简单的声明 –

+0

我想用一组值来初始化,我想将它传递给单例。我怎样才能做到这一点?你的例子正在用空hashmap进行初始化。 –

+1

@java_mouse:就是这样。没有办法从外部向构造函数传递任何东西,'enum'单例不会帮助你。 –

1
public enum BitCheck { 

    INSTANCE; 

    private BitCheck() { 
     // initialize here 
    } 

} 
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); 
    } 
} 
+0

+1,你应该以某种方式同步“道具”。 –

+0

是的。谢谢改变它。 –

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。