zoukankan      html  css  js  c++  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 }

    工具包类

    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_

  • 相关阅读:
    AtCoder Regular Contest 061
    Codeforces Round #370 (Div. 2)
    2016 ACM/ICPC Asia Regional Dalian Online
    HDU 5513 Efficient Tree
    Codeforces Round #104 (Div. 1)
    2016 Hunan Province Programming Contest
    2016 Multi-University Training Contest 7
    2016中国大学生程序设计竞赛
    聚会「AHOI 2008」
    游戏「AHOI / HNOI2018」
  • 原文地址:https://www.cnblogs.com/draem0507/p/4110987.html
Copyright © 2011-2022 走看看