Как инициализировать синглтон на основе enum Java?
Каков правильный способ инициализации синтаксиса на основе 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"));
}
}
Ответы
Ответ 1
Совершенно возможно создать конструктор для enum
:
public enum BitCheck {
INSTANCE;
BitCheck() {
props = new HashMap<String, String>();
}
private final Map<String, String> props;
//..
}
Обратите внимание, что:
-
props
поле может быть окончательным (нам нравится final
)
-
props
не должно быть static
Конструктор - вызывается автоматически и с нетерпением для вас
Обратите внимание на последнюю точку. Поскольку enum
-singletons создаются с нетерпением, когда класс enum BitCheck
загружен, у вас нет способа передать какие-либо аргументы конструктору. Конечно, вы можете через объявление INSTANCE
:
public enum BitCheck {
INSTANCE(new HashMap<String, String>());
BitCheck(final Map<String, String> props) {
this.props = props;
}
но это не имеет никакого значения, не так ли? Чего вы хотите достичь? Может быть, вам действительно нужен ленивый инициализированный синглтон?
Ответ 2
Вам нужно просто инициализировать его в объявлении.
public enum BitCheck {
INSTANCE;
private final Map<String, String> props = new ConcurrentHashMap<String, String>();
public void putAll(HashMap<String, String> map) {
props.putAll(map);
}
}
Ответ 3
Вам нужно определить конструктор следующим образом:
public enum BitCheck {
INSTANCE;
private final HashMap<String, String> props;
BitCheck() {
}
}
Очень хорошим примером является перечисление Планеты по адресу: http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
Ответ 4
public enum BitCheck {
INSTANCE;
private BitCheck() {
// initialize here
}
}
Ответ 5
Вы должны реализовать интерфейс и, следовательно, изменить на:
private Map<...> props;
Вы можете посмотреть Каков наилучший подход для использования Enum в качестве одноэлементного в Java?, который похож на то, что вы хотите.
Ответ 6
Вы можете попробовать что-то подобное в своем одноэлементном коде на основе 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;
}
}
ПРИМЕЧАНИЕ. Для более сложной инициализации вам понадобится 2 AtomicBooleans для initStarted и initCompleted (вместо одиночного AtomicBoolean - isInitialized). Затем первый поток устанавливает initStarted и выполняет шаги инициализации, остальные ждут, пока initCompleted не будет установлен в true нитью.