我经常在我的代码中使用这种设计来维护可配置的值。考虑这段代码:
public enum Options {
REGEX_STRING("Some Regex"),
REGEX_PATTERN(Pattern.compile(REGEX_STRING.getString()), false),
THREAD_COUNT(2),
OPTIONS_PATH("options.config", false),
DEBUG(true),
ALWAYS_SAVE_OPTIONS(true),
THREAD_WAIT_MILLIS(1000);
Object value;
boolean saveValue = true;
private Options(Object value) {
this.value = value;
}
private Options(Object value, boolean saveValue) {
this.value = value;
this.saveValue = saveValue;
}
public void setValue(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public String getString() {
return value.toString();
}
public boolean getBoolean() {
Boolean booleanValue = (value instanceof Boolean) ? (Boolean) value : null;
if (value == null) {
try {
booleanValue = Boolean.valueOf(value.toString());
}
catch (Throwable t) {
}
}
// We want a NullPointerException here
return booleanValue.booleanValue();
}
public int getInteger() {
Integer integerValue = (value instanceof Number) ? ((Number) value).intValue() : null;
if (integerValue == null) {
try {
integerValue = Integer.valueOf(value.toString());
}
catch (Throwable t) {
}
}
return integerValue.intValue();
}
public float getFloat() {
Float floatValue = (value instanceof Number) ? ((Number) value).floatValue() : null;
if (floatValue == null) {
try {
floatValue = Float.valueOf(value.toString());
}
catch (Throwable t) {
}
}
return floatValue.floatValue();
}
public static void saveToFile(String path) throws IOException {
FileWriter fw = new FileWriter(path);
Properties properties = new Properties();
for (Options option : Options.values()) {
if (option.saveValue) {
properties.setProperty(option.name(), option.getString());
}
}
if (DEBUG.getBoolean()) {
properties.list(System.out);
}
properties.store(fw, null);
}
public static void loadFromFile(String path) throws IOException {
FileReader fr = new FileReader(path);
Properties properties = new Properties();
properties.load(fr);
if (DEBUG.getBoolean()) {
properties.list(System.out);
}
Object value = null;
for (Options option : Options.values()) {
if (option.saveValue) {
Class<?> clazz = option.value.getClass();
try {
if (String.class.equals(clazz)) {
value = properties.getProperty(option.name());
}
else {
value = clazz.getConstructor(String.class).newInstance(properties.getProperty(option.name()));
}
}
catch (NoSuchMethodException ex) {
Debug.log(ex);
}
catch (InstantiationException ex) {
Debug.log(ex);
}
catch (IllegalAccessException ex) {
Debug.log(ex);
}
catch (IllegalArgumentException ex) {
Debug.log(ex);
}
catch (InvocationTargetException ex) {
Debug.log(ex);
}
if (value != null) {
option.setValue(value);
}
}
}
}
}
这样,我就可以轻松地从文件中保存和检索值。问题是我不想到处重复这段代码。正如我们所知,枚举不能扩展;所以无论我在哪里使用它,我都必须将所有这些方法放在那里。我只想声明这些值以及它们是否应该保留。每次都没有方法定义;有什么想法吗?
最佳答案
像这样使用enum
来保存可配置的值看起来是一个完全错误的设计。枚举是单例,因此实际上您在任何给定时间只能激活一个配置。
EnumMap
听起来更像您所需要的。它在 enum
外部,因此您可以根据需要实例化任意数量的配置。
import java.util.*;
public class EnumMapExample {
static enum Options {
DEBUG, ALWAYS_SAVE, THREAD_COUNT;
}
public static void main(String[] args) {
Map<Options,Object> normalConfig = new EnumMap<Options,Object>(Options.class);
normalConfig.put(Options.DEBUG, false);
normalConfig.put(Options.THREAD_COUNT, 3);
System.out.println(normalConfig);
// prints "{DEBUG=false, THREAD_COUNT=3}"
Map<Options,Object> debugConfig = new EnumMap<Options,Object>(Options.class);
debugConfig.put(Options.DEBUG, true);
debugConfig.put(Options.THREAD_COUNT, 666);
System.out.println(debugConfig);
// prints "{DEBUG=true, THREAD_COUNT=666}"
}
}
API 链接
-
java.util.EnumMap
A specialized
Map
implementation for use withenum
type keys. All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created. Enum maps are represented internally as arrays. This representation is extremely compact and efficient.
关于java - 枚举中的可配置值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2902113/