java反射之获取class对象_java反射之获取枚举对象

本文探讨如何利用Java反射解决项目中大量枚举对象通过key获取枚举的冗余问题。通过创建一个通用的接口`EnumMessage`,并让多个枚举实现该接口,再结合反射动态获取枚举对象,避免了重复代码。示例代码展示了如何通过反射从枚举类中获取枚举对象,简化枚举的管理和维护。
摘要由CSDN通过智能技术生成

项目中导入大量枚举对象,用来定义常量。随着带来一个问题,就是每个枚举类都需要通过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 ENUM_OBJECT_PATH = PackageUtil.getPackageClasses(PACKAGE_NAME, true);

/**

* 存放单个枚举对象 map常量定义

*/

private static Map SINGLE_ENUM_MAP = null;

/**

* 所有枚举对象的 map

*/

public static final Map> ENUM_MAP = initialEnumMap(true);

/**静态初始化块*/

static {

}

/**

* 加载所有枚举对象数据

* @param isFouceCheck 是否强制校验枚举是否实现了EnumMessage接口

*

* */

private static Map> initialEnumMap(boolean isFouceCheck){

Map> ENUM_MAP = new HashMap>();

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();

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 包下所有的类

* */

public static List getPackageClasses(String packagePath){

return getPackageClasses(packagePath,false);

}

/**

* 返回包下所有的类

* @param packagePath 包名全路径

* @param classWithPath 返回全路径开关 true 自动带上包名

* @return List 包下所有的类

* */

public static List getPackageClasses(String packagePath,boolean classWithPath){

List classNames = getClassName(packagePath);

Listresult =new ArrayList(classNames.size());

String path =classWithPath?packagePath+".":"";

for (String className : classNames) {

result.add(path+className.substring(className.lastIndexOf(".")+1));

}

return result;

}

private static List getClassName(String packageName) {

String filePath = ClassLoader.getSystemResource("").getPath() + packageName.replace(".", "\\");

List fileNames = getClassName(filePath, null);

return fileNames;

}

private static List getClassName(String filePath, List className) {

List myClassName = new ArrayList();

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 getEnumObject(int value,Class 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 根据值获取枚举对象

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

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

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

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

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

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

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

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

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

java根据url获取json对象

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

Java 反射 分析类和对象

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

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

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

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

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

随机推荐

tomcat-8.0

https://tomcat.apache.org/tomcat-8.0-doc/introduction.html

Vim 第一天

记得第一次接触vi编辑器,好像是在海尔的机房吧,那是时候还是没有毕业的小菜鸟一只(PS:现在也是菜鸟),记得是测试一个云存储的产品.看着他们用vi编辑器,当时也没有感觉有什么(现在也没感觉……),只是 ...

【以2-SAT为主题的婚礼UVA11294】

·新娘头饰复杂,这个婚礼怪异非凡. ·英文题,述大意:        婚宴上,有一个很长的桌子.桌子两边坐人(即人们坐成两排).新娘坐在其中一排,只能看见桌子对面所有的人.输入的m表示有m对人打过架. ...

【数据库】+ powerdesigner

使用powerdesigner工具对现有数据库表 生成关系图:https://www.cnblogs.com/lusunqing/p/4128025.html 通过Excel生成PowerDesign ...

说说Python中的闭包

Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...

android 判断横竖屏的方法(转)

public boolean isScreenChange() { Configuration mConfiguration = this.getResources().getConfiguratio ...

scrapy-redis(调度器Scheduler源码分析)

settings里面的配置:'''当下面配置了这个(scrapy-redis)时候,下面的调度器已经配置在scrapy-redis里面了'''##########连接配置######## REDIS_ ...

java.lang.NoClassDefFoundError: net.tsz.afinal.FinalHttp

java.lang.NoClassDefFoundError: net.tsz.afinal.FinalHttpat com.hbjyjt.oa.utils.i.(HttpRe ...

thinkphp 构建子查询

thinkphp构建子查询sql语句写法        从3.0版本开始新增了子查询支持,有两种使用方式: 1.使用select方法 当select方法的参数为false的时候,表示不进行查询只是 ...

Unity -- 材质-Material和预设体-Prefabs

材质(Materials)用来把网格(Mesh)或粒子渲染器(Particle Renderers)贴到游戏对象上.他们在定义对象怎么被显示发挥重要组成部分.材质包括用于呈现网状或颗粒着色器的参考,所 ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值