一个字段有各种值代表不同意思,我们开发时,一定会想到用枚举表示。
一段常见的枚举类定义如下:
public enum EventGroupTypeEnum {
SN(0),
TAG(1),
USER(2);
private int value;
EventGroupTypeEnum(int value){
this.value = value;
}
public int getValue() {
return value;
}
}
于是,代码中,我们使用EventGroupTypeEnum.SN.getValue(),代表这里是SN类型的值,将对应的value=0,存入了数据库。
场景一,有天,我们要检验一个值是否是这个枚举里的值。
我们希望这个枚举类能够使用起来像mapper那样的方便。
Map<String, String> map = new HashMap<>();
map.put(0,sn);
....
public boolean exitValue(int value) {
String result = map.get(value);
return null == result ? false: true;
}
实际情况是,枚举类没有提供这么方便的操作。让人感觉恼火,明明就在那,明确声明了,确认使用不上。
场景二,现有页面的列表页有个字段,需要把枚举字段的值,都翻译为汉字意思显示。
我们前面的枚举类定义,根本没有汉字啊。于是乎,偷懒的人就这么写了
<c:if test="${value=0}">串号</c:if>
<c:if test="..">..</c:if>
....
这个显然是硬伤代码,每个地方大量手写,有变动那就是灾难级别的维护。
场景三,页面的查询条件中,需要把枚举类型的值,都列表出来供选择。显然下拉框看到的肯定是汉字意思。
再像场景二那样编码,真的维护起来就是哭的昏天暗地啊。
那怎么解决上面的需求,让枚举值,一处边写,多处复用。
枚举工具类
首先,我们的枚举,需要把汉字意思也写入。我们之前的枚举类的定义,显然,只考虑的java编写的名称和对应的value,而忘了写对应的汉字意思。
我们可以这样定义:
public enum EventGroupTypeEnum {
SN(0, "串号"),
TAG(1, "标签组"),
USER(2, "业务分组");
private int value;
private String name;
EventGroupTypeEnum(int value, String name){
this.value = value;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}
然后,我们的工具类如下:
场景一,枚举值验证
public void enumValueValid(String enumValue, Class enumClass) {
boolean exit = false;
try {
Method method = enumClass.getDeclaredMethod("values");
Object[] objects = (Object[]) method.invoke(enumClass);
for (Object o : objects) {
Method method1 = o.getClass().getDeclaredMethod("getValue");
String value = method1.invoke(o).toString();
if (value.equals(enumValue) && !exit) {
exit = true;
}
}
} catch (Exception e) {
log.warn("枚举验证异常: {}", e.getMessage());
throw new RuntimeException(e.getMessage());
}
if (!exit) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("枚举类:").append(enumClass.getName()).append(",没有枚举值: ").append(enumValue);
log.warn(stringBuilder.toString());
throw new RuntimeException(stringBuilder.toString());
}
}
场景二,根据value值,像map一样的获取对应的汉字意思
// 根据value值,像map一样的获取对应的汉字意思
public static String getEnumName(String value, String className) {
try {
Class enumClass = Class.forName(ENUM_PACKAGE+className);
Method method = enumClass.getDeclaredMethod("values");
Object[] objects = (Object[]) method.invoke(enumClass);
for (Object o : objects) {
Method method1 = o.getClass().getDeclaredMethod("getValue");
String enumValue = method1.invoke(o).toString();
if (value.equals(enumValue)) {
return o.getClass().getDeclaredMethod("getName").invoke(o).toString();
}
}
} catch (Exception cne) {
return value;
}
return value;
}
场景三,获得枚举列表,值和汉字意思
public static List<KeyValue> changeEnumsToList(String className) {
List<KeyValue> keyValues;
try {
Class enumClass = Class.forName(ENUM_PACKAGE+className);
Method method = enumClass.getDeclaredMethod("values");
Object[] objects = (Object[]) method.invoke(enumClass);
keyValues = new ArrayList<>(objects.length);
for (Object o : objects) {
String key = o.getClass().getDeclaredMethod("getValue").invoke(o).toString();
String name = o.getClass().getDeclaredMethod("getName").invoke(o).toString();
KeyValue kv = new KeyValue();
kv.setKey(key);
kv.setValue(name);
keyValues.add(kv);
}
} catch (Exception cne) {
return Collections.emptyList();
}
return keyValues;
}
到这里,枚举类常用的三个场景,我们就可以轻松解决了。
小编技术有限,还有什么好的建议,欢迎留言。