项目中导入大量枚举对象,用来定义常量。随着带来一个问题,就是每个枚举类都需要通过key来获取对应枚举的需求。
1 public enumExamType {2 CRAFT(1, "草稿"),3 PASSING(2, "待审核");4 private intvalue;5 privateString typeName;6
7 ExamType(intvalue, String typeName) {8 this.value =value;9 this.typeName =typeName;10 }11 //通过value获取对应的枚举对象
12 public static ExamType getExamType(intvalue) {13 for(ExamType examType : ExamType.values()) {14 if (value ==examType.getValue()) {15 returnexamType;16 }17 }18 return null;19 }20
21
22 }
随着项目的增大,可能存在很多枚举对象都需要,可能都需要去实现一样的方式,就存在了代码冗余的问题,可惜enum对象又不不能继承其他类
(默认继承Enum)。所以考虑说使用反射来替代之前的方式
为了方便,将代码写带一个类中
1 //接口类
2 public interfaceEnumMessage {3 Integer getValue();4 String getMessage();5 }6
7 //枚举类
8 public enum AccountStatus implementsEnumMessage {9 Init(0,"初始化"),10 Ready(1,"正常"),11 ChangePassword(2,"需要修改密码"),12 Frozen(4,"冻结"),13 Disabled(64,"禁用"),14 ;15 private finalInteger _code;16 private finalString _message;17 AccountStatus(Integer code,String message){18 _code=code;19 _message=message;20 }21 @Override22 public Integer getValue() { return_code;}23 @Override24 public String getMessage() { return_message; }25 }26
27
28 public enum AuditNotifyStatus implementsEnumMessage {29 Sms(2,"短信"),30 Mail(4,"邮箱"),31 SmsAndMail(6,"短信和邮箱"),32 ;33 private finalInteger _code;34 private finalString _message;35 AuditNotifyStatus(Integer code,String message){36 _code=code;37 _message=message;38 }39 @Override40 public Integer getValue() { return_code;}41 @Override42 public String getMessage() { return_message; }43 }
常量类
1 public classConstant {2
3
4 /**
5 * 枚举类对应的包路径6 */
7 public final static String PACKAGE_NAME = "com.lwx.util.reflex.enums";8 /**
9 * 枚举接口类全路径10 */
11 public final static String ENUM_MESSAGE_PATH=PACKAGE_NAME+".EnumMessage";12
13 /**
14 * 枚举类对应的全路径集合15 */
16 public static final List ENUM_OBJECT_PATH = PackageUtil.getPackageClasses(PACKAGE_NAME, true);17
18 /**
19 * 存放单个枚举对象 map常量定义20 */
21 private static Map SINGLE_ENUM_MAP = null;22 /**
23 * 所有枚举对象的 map24 */
25 public static final Map> ENUM_MAP = initialEnumMap(true);26
27
28 /**静态初始化块*/
29 static{30
31 }32
33 /**
34 * 加载所有枚举对象数据35 *@paramisFouceCheck 是否强制校验枚举是否实现了EnumMessage接口36 *37 **/
38 private static Map> initialEnumMap(booleanisFouceCheck){39 Map> ENUM_MAP = new HashMap>();40 try{41 for(String classname : ENUM_OBJECT_PATH) {42 Class> cls = null;43 cls =Class.forName(classname);44 Class >[]iter=cls.getInterfaces();45 boolean flag=false;46 if(isFouceCheck){47 for(Class cz:iter){48 if(cz.getName().equals(ENUM_MESSAGE_PATH)){49 flag=true;50 break;51 }52 }53 }54 if(flag==isFouceCheck){55 SINGLE_ENUM_MAP = new HashMap();56 initialSingleEnumMap(cls);57 ENUM_MAP.put(cls, SINGLE_ENUM_MAP);58 }59
60 }61 } catch(Exception e) {62
63 }64 returnENUM_MAP;65 }66
67 /**
68 * 加载每个枚举对象数据69 **/
70 private static void initialSingleEnumMap(Class> cls )throwsException{71 Method method = cls.getMethod("values");72 EnumMessage inter[] = (EnumMessage[]) method.invoke(null, null);73 for(EnumMessage enumMessage : inter) {74 SINGLE_ENUM_MAP.put(enumMessage.getValue(), enumMessage);75 }76 }77
78
79 }
工具包类
public classPackageUtil {/*** 返回包下所有的类
*@parampackagePath 包名
*@returnList 包下所有的类
**/
public static ListgetPackageClasses(String packagePath){return getPackageClasses(packagePath,false);
}/*** 返回包下所有的类
*@parampackagePath 包名全路径
*@paramclassWithPath 返回全路径开关 true 自动带上包名
*@returnList 包下所有的类
**/
public static List getPackageClasses(String packagePath,booleanclassWithPath){
List classNames =getClassName(packagePath);
Listresult =new ArrayList(classNames.size());
String path=classWithPath?packagePath+".":"";for(String className : classNames) {
result.add(path+className.substring(className.lastIndexOf(".")+1));
}returnresult;
}private static ListgetClassName(String packageName) {
String filePath= ClassLoader.getSystemResource("").getPath() + packageName.replace(".", "\\");
List fileNames = getClassName(filePath, null);returnfileNames;
}private static List getClassName(String filePath, ListclassName) {
List myClassName = new ArrayList();
File file= newFile(filePath);
File[] childFiles=file.listFiles();for(File childFile : childFiles) {if(childFile.isDirectory()) {
myClassName.addAll(getClassName(childFile.getPath(), myClassName));
}else{
String childFilePath=childFile.getPath();
childFilePath= childFilePath.substring(childFilePath.indexOf("\\classes") + 9, childFilePath.lastIndexOf("."));
childFilePath= childFilePath.replace("\\", ".");
myClassName.add(childFilePath);
}
}returnmyClassName;
}
}
View Code
核心的获取枚举对象的类
1 public classEnumUtil {2
3
4 /**
5 * 获取value返回枚举对象6 *@paramvalue7 *@paramclazz8 **/
9 public static T getEnumObject(int value,Classclazz){10 return(T)Constant.ENUM_MAP.get(clazz).get(value);11 }12
13
14 }
测试
public static voidmain(String[] args) {
System.out.println(EnumUtil.getEnumObject(2, AuditNotifyStatus.class).getMessage());;//短信
System.out.println(EnumUtil.getEnumObject(6, AuditNotifyStatus.class).getMessage());;//短信和邮箱
}
拓展与参考
1.获取变量的值
1 public classTest {2 public static voidmain(String[] args) {3 //构造对象
4 User user = newUser();5 String strs[] ={"1","2","3"};6 user.setStrs(strs);7
8 Method[] methods =user.getClass().getMethods();9 for(Method m:methods){10 String methodNames=m.getName();11 if(methodNames.equals("getStrs")){12 try{13 Object obj =m.invoke(user, newObject[]{});14 if(obj instanceofjava.lang.String []){15 String tempstrs [] =(String[]) obj;16 for(String str:tempstrs){17 System.out.println(str);18 }19 }20 } catch(Exception e) {21 e.printStackTrace();22 }23 }24 }25 }26 }27 classUser{28 privateString strs[];29
30 publicString[] getStrs() {31 returnstrs;32 }33
34 public voidsetStrs(String[] strs) {35 this.strs =strs;36 }37 }
View Code
2.关于枚举的介绍(枚举无法通过newInstance来进行实力,本身构造就不能public,其实也就是规范)
http://whitesock.iteye.com/blog/728934
3.java反射获取注解
http://blog.csdn.net/lufeng20/article/details/8835135
http://blog.csdn.net/liyangbing315/article/details/5181381
4.使用反射+注解完成库表设计
http://blog.csdn.net/lufeng20/article/details/8730604
5.enum的使用,包含enumMap/enumSet
http://wenku.baidu.com/link?url=1y8U2qovo-oJkRmUBR_7sXkivFLxExzCW0J6hunDVcfIij08MX4RS45_eLptBGrujzS3q4tiGwsF4PmoGx032RBWj1IMmzOn6693B2YBVe_