Java中Enum的优雅用法
本文简单总结一些Java中enum的坑以及优雅的用法。
普通的enum有什么问题
- 分布式系统中由enum引起的问题
分布式系统中,系统间调用如果返回值中有enum类型的话,如果服务提供方改变,调用方没有改,就会报错,而且这个本该是业务层面的问题要在系统服务层才能看到报错信息,不利于系统维护。 - 数据库存储问题
enum的命名通常都是完整含义的单词,会很长,放数据库中占空间很多,而且不同的中间件存的数据类型也不一样。 - 和前端的交互问题
一般的web框架或者json对enum处理要么是字符串(name),要么序数(ordinal),字符串不利于沟通,容易拼写错误 - 不要用序数(ordinal)
以上问题都可以用一个通用的解决方法:将enum转成int,有的会支持直接用ordinal,但这并不是最优解法,因为用ordinal就不能随意改动enum定义的顺序,而且还不能自定义值。
优雅用法:带自定义id的enum
优雅的用法是在enum中定义int值,并在构造方法限定int值。举个例子:
/**
* 性别
*/
public enum Gender {
/**
* 男
*/
MALE(1),
/**
* 女
*/
FEMALE(0),
/**
* 保密
*/
SECURITY(2),
;
private int id;
Gender(int id) {
this.id = id;
}
public static Gender getInstance(int id) {
for (Gender tmp : Gender.values()) {
if (tmp.id == id) {
return tmp;
}
}
return null;
}
public int getId() {
return id;
}
}
这样就可以在其他地方获取id,也可以根据id获取对应enum。
通用Enum工具
但是这样每定义一种enum就得写一个getInstance方法,还是不够优雅,处理思路是写一个通用的工具方法来做这个事情。
首先定义一个通用enum的接口:
public interface IdEnum {
int getId();
}
然后让定义的enum实现这个接口:
/**
* 性别
*/
public enum Gender implements IdEnum {
/**
* 男
*/
MALE(1),
/**
* 女
*/
FEMALE(0),
/**
* 保密
*/
SECURITY(2),
;
private int id;
Gender(int id) {
this.id = id;
}
@Override
public int getId() {
return id;
}
}
这里就不需要getInstance方法了,直接利用Java的泛型特性写一个通用的获取方法:
public class EnumUtil {
public static <T extends IdEnum> T valueOf(Class<T> enumType, int id) {
for (T value : enumType.getEnumConstants()) {
if (value.getId() == id) {
return value;
}
}
return null;
}
}
网友评论