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 }

工具包类

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_

 

posted @ 2014-11-20 16:56  draem0507  阅读(33987)  评论(2编辑  收藏  举报
View Code