项目中导入大量枚举对象,用来定义常量。随着带来一个问题,就是每个枚举类都需要通过key来获取对应枚举的需求。

 public enum ExamType {
CRAFT(1, "草稿"),
PASSING(2, "待审核");
private int value;
private String typeName; ExamType(int value, String typeName) {
this.value = value;
this.typeName = typeName;
}
//通过value获取对应的枚举对象
public static ExamType getExamType(int value) {
for (ExamType examType : ExamType.values()) {
if (value == examType.getValue()) {
return examType;
}
}
return null;
} }

随着项目的增大,可能存在很多枚举对象都需要,可能都需要去实现一样的方式,就存在了代码冗余的问题,可惜enum对象又不不能继承其他类

(默认继承Enum)。所以考虑说使用反射来替代之前的方式

为了方便,将代码写带一个类中

 //接口类
public interface EnumMessage {
Integer getValue();
String getMessage();
} //枚举类
public enum AccountStatus implements EnumMessage {
Init(0,"初始化"),
Ready(1,"正常"),
ChangePassword(2,"需要修改密码"),
Frozen(4,"冻结"),
Disabled(64,"禁用"),
;
private final Integer _code;
private final String _message;
AccountStatus(Integer code,String message){
_code=code;
_message=message;
}
@Override
public Integer getValue() { return _code;}
@Override
public String getMessage() { return _message; }
} public enum AuditNotifyStatus implements EnumMessage {
Sms(2,"短信"),
Mail(4,"邮箱"),
SmsAndMail(6,"短信和邮箱"),
;
private final Integer _code;
private final String _message;
AuditNotifyStatus(Integer code,String message){
_code=code;
_message=message;
}
@Override
public Integer getValue() { return _code;}
@Override
public String getMessage() { return _message; }
}

常量类

 public class Constant {

     /**
* 枚举类对应的包路径
*/
public final static String PACKAGE_NAME = "com.lwx.util.reflex.enums";
/**
* 枚举接口类全路径
*/
public final static String ENUM_MESSAGE_PATH=PACKAGE_NAME+".EnumMessage"; /**
* 枚举类对应的全路径集合
*/
public static final List<String> ENUM_OBJECT_PATH = PackageUtil.getPackageClasses(PACKAGE_NAME, true); /**
* 存放单个枚举对象 map常量定义
*/
private static Map<Integer, EnumMessage> SINGLE_ENUM_MAP = null;
/**
* 所有枚举对象的 map
*/
public static final Map<Class, Map<Integer, EnumMessage>> ENUM_MAP = initialEnumMap(true); /**静态初始化块*/
static { } /**
* 加载所有枚举对象数据
* @param isFouceCheck 是否强制校验枚举是否实现了EnumMessage接口
*
* */
private static Map<Class, Map<Integer, EnumMessage>> initialEnumMap(boolean isFouceCheck){
Map<Class, Map<Integer, EnumMessage>> ENUM_MAP = new HashMap<Class, Map<Integer, EnumMessage>>();
try {
for (String classname : ENUM_OBJECT_PATH) {
Class<?> cls = null;
cls = Class.forName(classname);
Class <?>[]iter=cls.getInterfaces();
boolean flag=false;
if(isFouceCheck){
for(Class cz:iter){
if(cz.getName().equals(ENUM_MESSAGE_PATH)){
flag=true;
break;
}
}
}
if(flag==isFouceCheck){
SINGLE_ENUM_MAP = new HashMap<Integer, EnumMessage>();
initialSingleEnumMap(cls);
ENUM_MAP.put(cls, SINGLE_ENUM_MAP);
} }
} catch (Exception e) { }
return ENUM_MAP;
} /**
* 加载每个枚举对象数据
* */
private static void initialSingleEnumMap(Class<?> cls )throws Exception{
Method method = cls.getMethod("values");
EnumMessage inter[] = (EnumMessage[]) method.invoke(null, null);
for (EnumMessage enumMessage : inter) {
SINGLE_ENUM_MAP.put(enumMessage.getValue(), enumMessage);
}
} }

工具包类

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

核心的获取枚举对象的类

 public class EnumUtil {

     /**
* 获取value返回枚举对象
* @param value
* @param clazz
* */
public static <T extends EnumMessage> T getEnumObject(int value,Class<T> clazz){
return (T)Constant.ENUM_MAP.get(clazz).get(value);
} }

测试

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

 public class Test {
public static void main(String[] args) {
//构造对象
User user = new User();
String strs[] ={"1","2","3"};
user.setStrs(strs); Method[] methods = user.getClass().getMethods();
for(Method m:methods){
String methodNames= m.getName();
if(methodNames.equals("getStrs")){
try {
Object obj =m.invoke(user, new Object[]{});
if(obj instanceof java.lang.String []){
String tempstrs [] =(String[]) obj;
for(String str:tempstrs){
System.out.println(str);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
class User{
private String strs[]; public String[] getStrs() {
return strs;
} public void setStrs(String[] strs) {
this.strs = strs;
}
}

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反射之获取枚举对象的更多相关文章

  1. java 根据值获取枚举对象

    关键方法: /** * 值映射为枚举 * * @param enumClass 枚举类 * @param value 枚举值 * @param method 取值方法 * @param <E&g ...

  2. Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)

    反射技术其实就是动态加载一个指定的类,并获取该类中的所有内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员,简单来说:反射技术可以对一个类进行解剖,反射大大增强 ...

  3. java 反射之获取泛型对象的所有字段与对应的值(包括父类的)

    上代码: public static void main(String[] args) throws IntrospectionException { SysUser obj = new SysUse ...

  4. 第三章 EnumUtil根据值获取枚举对象

    项目中使用枚举类的好处这里不再赘述,在使用枚举值时,通常需要根据值来获取枚举对象,下面介绍两种实现方案: 1.在枚举类中定义方法实现 首先给出如下性别枚举类: public enum SexEnum ...

  5. java反射机制获取自定义注解值和方法

    由于工作需求要应用到java反射机制,就做了一下功能demo想到这些就做了一下记录 这个demo目的是实现动态获取到定时器的方法好注解名称,废话不多说了直接上源码 1.首先需要自定义注解类 /** * ...

  6. java根据url获取json对象

    package test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; ...

  7. Java 反射 分析类和对象

    Java 反射 分析类和对象 @author ixenos 摘要:优化程序启动策略.在运行时使用反射分析类的结构和对象 优化程序启动策略 在启动时,包含main方法的类被加载.它会加载所有它需要的类. ...

  8. java反射之获取所有方法及其注解(包括实现的接口上的注解),获取各种标识符备忘

    java反射之获取类或接口上的所有方法及其注解(包括实现的接口上的注解) /** * 获取类或接口上的所有方法及方法上的注解(包括方法实现上的注解以及接口上的注解),最完整的工具类,没有现成的工具类 ...

  9. .NET(C#):使用反射来获取枚举的名称、值和特性【转】

    首先需要从内部了解一下枚举(Enumeration),相信许多人已经知道了,当我们声明一个这样的枚举类型: enumMyEnum { AAA, BBB, CCC } 背后的IL是这样的: .class ...

随机推荐

  1. php+C#.net混合开发

    php+C#.net混合开发 上图一张,左右是php语言,右边是C#语言,解决方案中的php项目是红色的小标识

  2. windows系统tomcat日志输出至catalina.out配置说明

    转自:https://blog.csdn.net/liubowin/article/details/48001947 1.修改bin/startup.bat文件 修改前:call "%EXE ...

  3. Android Studio打开出现:Default activity not found

    昨天项目可以正常打开,没有问题,今天打开的时候就出现了这个问题.可以编译,但是无法生成APK调试.当然,如果选择 Do not launch Activity就可以成功编译.出现这个 Default ...

  4. Office办公 如何设置WPS的默认背景大小

    设计-页面设置,然后修改宽度和高度   因为我们只是需要背景跟平面差不多大(不同屏幕比如宽屏的就比较长),修改宽度和高度的时候注意文字之类的也会被拉伸缩放,所以自己改了之后看效果,比如我100,50的 ...

  5. ArcGIS10.3新体验

    自2012年ESRI更新10.2以后,终于在2014年12月8日,官方推出了10.3版本,前几天忙于抢票,今天终于可以在虚拟机中体验一把. 由于使用的是预览版,所有安装包只有800多M,包括桌面核心程 ...

  6. javascript编程思想

    javascript编程开发修炼之道   提要文摘附注: 本文的核心内容是围绕javascript前端开发的编程技术要素,来深入地探讨编写高质量的javascript代码的方法.技巧.规范和最佳实践, ...

  7. hive中简单介绍分区表(partition table)——动态分区(dynamic partition)、静态分区(static partition)

    一.基本概念 hive中分区表分为:范围分区.列表分区.hash分区.混合分区等. 分区列:分区列不是表中的一个实际的字段,而是一个或者多个伪列.翻译一下是:“在表的数据文件中实际上并不保存分区列的信 ...

  8. tortoisegit 右键无图标

    如果你安装 TortoiseGit之后,发现文件夹或文件左上角就是不显示图标,那么以下步骤就是最好的解决办法. 工具/原料   TortoiseGit 方法/步骤     确认是不是64bit 系统上 ...

  9. 使用sphinx自动提取python中的注释成为接口文档

    写好了代码,交付给他人使用的时候,查看代码固然可以了解各类和函数的功能细节,但接口文档能更方便的查找和说明功能.所以,一价与代码同步的接口文档是很有必要的.sphinx可以根据python中的注释,自 ...

  10. Java多线程中的内存模型

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6536131.html  一:现代计算机的高速缓存 在计算机组成原理中讲到,现代计算机为了匹配 计算机存储设备的 ...