项目中导入大量枚举对象,用来定义常量。随着带来一个问题,就是每个枚举类都需要通过key来获取对应枚举的需求。
1 public enum ExamType { 2 CRAFT(1, "草稿"), 3 PASSING(2, "待审核"); 4 private int value; 5 private String typeName; 6 7 ExamType(int value, String typeName) { 8 this.value = value; 9 this.typeName = typeName; 10 } 11 //通过value获取对应的枚举对象 12 public static ExamType getExamType(int value) { 13 for (ExamType examType : ExamType.values()) { 14 if (value == examType.getValue()) { 15 return examType; 16 } 17 } 18 return null; 19 } 20 21 22 }
随着项目的增大,可能存在很多枚举对象都需要,可能都需要去实现一样的方式,就存在了代码冗余的问题,可惜enum对象又不不能继承其他类
(默认继承Enum)。所以考虑说使用反射来替代之前的方式
为了方便,将代码写带一个类中
1 //接口类 2 public interface EnumMessage { 3 Integer getValue(); 4 String getMessage(); 5 } 6 7 //枚举类 8 public enum AccountStatus implements EnumMessage { 9 Init(0,"初始化"), 10 Ready(1,"正常"), 11 ChangePassword(2,"需要修改密码"), 12 Frozen(4,"冻结"), 13 Disabled(64,"禁用"), 14 ; 15 private final Integer _code; 16 private final String _message; 17 AccountStatus(Integer code,String message){ 18 _code=code; 19 _message=message; 20 } 21 @Override 22 public Integer getValue() { return _code;} 23 @Override 24 public String getMessage() { return _message; } 25 } 26 27 28 public enum AuditNotifyStatus implements EnumMessage { 29 Sms(2,"短信"), 30 Mail(4,"邮箱"), 31 SmsAndMail(6,"短信和邮箱"), 32 ; 33 private final Integer _code; 34 private final String _message; 35 AuditNotifyStatus(Integer code,String message){ 36 _code=code; 37 _message=message; 38 } 39 @Override 40 public Integer getValue() { return _code;} 41 @Override 42 public String getMessage() { return _message; } 43 }
常量类
1 public class Constant { 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<String> ENUM_OBJECT_PATH = PackageUtil.getPackageClasses(PACKAGE_NAME, true); 17 18 /** 19 * 存放单个枚举对象 map常量定义 20 */ 21 private static Map<Integer, EnumMessage> SINGLE_ENUM_MAP = null; 22 /** 23 * 所有枚举对象的 map 24 */ 25 public static final Map<Class, Map<Integer, EnumMessage>> ENUM_MAP = initialEnumMap(true); 26 27 28 /**静态初始化块*/ 29 static { 30 31 } 32 33 /** 34 * 加载所有枚举对象数据 35 * @param isFouceCheck 是否强制校验枚举是否实现了EnumMessage接口 36 * 37 * */ 38 private static Map<Class, Map<Integer, EnumMessage>> initialEnumMap(boolean isFouceCheck){ 39 Map<Class, Map<Integer, EnumMessage>> ENUM_MAP = new HashMap<Class, Map<Integer, EnumMessage>>(); 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<Integer, EnumMessage>(); 56 initialSingleEnumMap(cls); 57 ENUM_MAP.put(cls, SINGLE_ENUM_MAP); 58 } 59 60 } 61 } catch (Exception e) { 62 63 } 64 return ENUM_MAP; 65 } 66 67 /** 68 * 加载每个枚举对象数据 69 * */ 70 private static void initialSingleEnumMap(Class<?> cls )throws Exception{ 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 class PackageUtil { /** * 返回包下所有的类 * @param packagePath 包名 * @return List<String> 包下所有的类 * */ public static List<String> getPackageClasses(String packagePath){ return getPackageClasses(packagePath,false); } /** * 返回包下所有的类 * @param packagePath 包名全路径 * @param classWithPath 返回全路径开关 true 自动带上包名 * @return List<String> 包下所有的类 * */ public static List<String> getPackageClasses(String packagePath,boolean classWithPath){ List<String> classNames = getClassName(packagePath); List<String>result =new ArrayList<String>(classNames.size()); String path =classWithPath?packagePath+".":""; for (String className : classNames) { result.add(path+className.substring(className.lastIndexOf(".")+1)); } return result; } private static List<String> getClassName(String packageName) { String filePath = ClassLoader.getSystemResource("").getPath() + packageName.replace(".", "\"); List<String> fileNames = getClassName(filePath, null); return fileNames; } private static List<String> getClassName(String filePath, List<String> className) { List<String> myClassName = new ArrayList<String>(); File file = new File(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); } } return myClassName; } }
核心的获取枚举对象的类
1 public class EnumUtil { 2 3 4 /** 5 * 获取value返回枚举对象 6 * @param value 7 * @param clazz 8 * */ 9 public static <T extends EnumMessage> T getEnumObject(int value,Class<T> clazz){ 10 return (T)Constant.ENUM_MAP.get(clazz).get(value); 11 } 12 13 14 }
测试
public static void main(String[] args) { System.out.println(EnumUtil.getEnumObject(2, AuditNotifyStatus.class).getMessage());;//短信 System.out.println(EnumUtil.getEnumObject(6, AuditNotifyStatus.class).getMessage());;//短信和邮箱 }
拓展与参考
1.获取变量的值
1 public class Test { 2 public static void main(String[] args) { 3 //构造对象 4 User user = new User(); 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, new Object[]{}); 14 if(obj instanceof java.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 class User{ 28 private String strs[]; 29 30 public String[] getStrs() { 31 return strs; 32 } 33 34 public void setStrs(String[] strs) { 35 this.strs = strs; 36 } 37 }
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_