首页 > 代码库 > java反射之获取枚举对象

java反射之获取枚举对象

项目中导入大量枚举对象,用来定义常量。随着带来一个问题,就是每个枚举类都需要通过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 =http://www.mamicode.com/ value; 9         this.typeName = typeName;10     }11     //通过value获取对应的枚举对象12       public static ExamType getExamType(int value) {13         for (ExamType examType : ExamType.values()) {14             if (value =http://www.mamicode.com/= 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     @Override22     public Integer getValue() { return _code;}23     @Override24     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     @Override40     public Integer getValue() { return _code;}41     @Override42     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      * 所有枚举对象的 map24      */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;      }  }
View Code

核心的获取枚举对象的类

 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 }
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_

 

java反射之获取枚举对象