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 = 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 }
复制代码

工具包类

 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.获取变量的值

 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_

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页