java枚举的集中管理

2023-10-30

java枚举的集中管理
一、 产品中遇到的实际情况枚举类泛滥
这个在这里插入图片描述
这个在这里插入图片描述
这个 在这里插入图片描述
这个 在这里插入图片描述

在 JDK 1.5 之前没有枚举类型,那时候一般用接口常量来替代。而使用 Java 枚举类型 enum 可以更贴近地表示这种常量。但是在项目中,就变成这样了

二、 如何实现统一管理枚举
整体思路就是让枚举的类变少,只存在被抽象出来的几个类型的枚举类,在需要使用的地方动态的构建为所需要的枚举类型赋予对应的值,就可以了
三、 对枚举进行抽象
其实多注意看一些枚举类型,就是 单值类型的,多值类型的,还有一些复杂类型的,这里定义了三种类型的枚举,单值类型的,多值类型String Int key,String value类型的,可以根据需要进行增加

在这里插入图片描述

/**

  • enum type is singal value
  • @author yuyang

*/
public enum SingalEnum {
;
}

/**

  • enum type is int key String value
  • @author yuyang

*/
public enum ISEnum {
;
private final int key;
private final String value;

private ISEnum(int key, String value) {
	this.key = key;
	this.value = value;
}

public int getKey() {
	return key;
}

public String getValue() {
	return value;
}

}

/**
*

  • enum type is String key String value
  • @author yuyang

*/
public enum SSEnum {

;
private final String key;
private final String value;

SSEnum(String key, String value) {
	this.key = key;
	this.value = value;
}

public String getKey() {
	return key;
}

public String getValue() {
	return value;
}

}

四、 动态构建枚举值

/**
*

  • @author yuyang

*/
public class EnumBuilderTools {

public static ObjectMapper mapper = JsonUtil.objectMapper();

/**
 * init enums jsonmap
 */
private static Map<String, Object> singalenumsjsonMap = null;

private static Map<String, Object> isenumsjsonMap = null;

static {
	try {
		InputStream singalenumsins = EnumBuilderTools.class.getClassLoader().getResourceAsStream("singalenums.json");
		InputStream isenumsins = EnumBuilderTools.class.getClassLoader().getResourceAsStream("isenums.json");

		singalenumsjsonMap = mapper.readValue(singalenumsins, Map.class);
		isenumsjsonMap = mapper.readValue(isenumsins, Map.class);
	} catch (JsonParseException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (JsonMappingException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

/**
 * 构建但单值型枚举
 * 
 * @param SingalEnumKey
 */
public static void buildSingalEnum(String SingalEnumKey) {
	ArrayList<String> arrys = (ArrayList<String>) singalenumsjsonMap.get(SingalEnumKey);
	for (int i = 0; i < arrys.size(); i++) {
		DynamicEnumUtil.addEnum(SingalEnum.class, arrys.get(i).toString());
	}
}

/**
 * 构建ISEnum 
 * 
 * @param ISEnumKey
 */
public static void buildISEnum(String ISEnumKey) {
	ArrayList<Map<String, String>> arrys = (ArrayList<Map<String, String>>) isenumsjsonMap.get(ISEnumKey);
	for (int i = 0; i < arrys.size(); i++) {
		Map<String, String> isenumValuemap = arrys.get(i);
		DynamicEnumUtil.addEnum(ISEnum.class, isenumValuemap.get("enumName"), new Class[] { int.class, String.class }, new Object[] { Integer.valueOf(isenumValuemap.get("key")), isenumValuemap.get("value").toString() });
	}
}

public static void main(String[] args) {
	buildSingalEnum("ClaimType");
	System.out.println(SingalEnum.valueOf("CHECKClAIM"));
	System.out.println(Arrays.deepToString(SingalEnum.values()));

	buildISEnum("InsuranceCompanyType");
	System.out.println(Arrays.deepToString(ISEnum.values()));
	System.out.println(ISEnum.valueOf("PingAn").getKey());
	System.out.println(ISEnum.valueOf("PingAn").getValue());
	
	ISEnum insuranceCompanyType = ISEnum.creator(String.valueOf(3));
	System.out.println(insuranceCompanyType);
	

}

}
这是创建所需的枚举类型的代码

动态枚举工具类是借鉴了大神的代码
/**

  • 动态枚举工具类
  • @author yuyang

*/
public class DynamicEnumUtil {

private static ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();

private static void setFailsafeFieldValue(Field field, Object target, Object value) throws NoSuchFieldException, IllegalAccessException {

	// let's make the field accessible
	field.setAccessible(true);

	// next we change the modifier in the Field instance to
	// not be final anymore, thus tricking reflection into
	// letting us modify the static final field
	Field modifiersField = Field.class.getDeclaredField("modifiers");
	modifiersField.setAccessible(true);
	int modifiers = modifiersField.getInt(field);

	// blank out the final bit in the modifiers int
	modifiers &= ~Modifier.FINAL;
	modifiersField.setInt(field, modifiers);

	FieldAccessor fa = reflectionFactory.newFieldAccessor(field, false);
	fa.set(target, value);
}

private static void blankField(Class<?> enumClass, String fieldName) throws NoSuchFieldException, IllegalAccessException {
	for (Field field : Class.class.getDeclaredFields()) {
		if (field.getName().contains(fieldName)) {
			AccessibleObject.setAccessible(new Field[] { field }, true);
			setFailsafeFieldValue(field, enumClass, null);
			break;
		}
	}
}

private static void cleanEnumCache(Class<?> enumClass) throws NoSuchFieldException, IllegalAccessException {
	blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK
													// 1.5/6
	blankField(enumClass, "enumConstants"); // IBM JDK
}

private static ConstructorAccessor getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes) throws NoSuchMethodException {
	Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
	parameterTypes[0] = String.class;
	parameterTypes[1] = int.class;
	System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
	return reflectionFactory.newConstructorAccessor(enumClass.getDeclaredConstructor(parameterTypes));
}

private static Object makeEnum(Class<?> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues) throws Exception {
	Object[] parms = new Object[additionalValues.length + 2];
	parms[0] = value;
	parms[1] = Integer.valueOf(ordinal);
	System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
	return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(parms));
}

/**
 * Add an enum instance to the enum class given as argument
 *
 * @param <T>      the type of the enum (implicit)
 * @param enumType the class of the enum to be modified
 * @param enumName the name of the new enum instance to be added to the class.
 */
@SuppressWarnings("unchecked")
public static <T extends Enum<?>> void addEnum(Class<T> enumType, String enumName) {

	// 0. Sanity checks
	if (!Enum.class.isAssignableFrom(enumType)) {
		throw new RuntimeException("class " + enumType + " is not an instance of Enum");
	}

	// 1. Lookup "$VALUES" holder in enum class and get previous enum
	// instances
	Field valuesField = null;
	Field[] fields = enumType.getDeclaredFields();
	for (Field field : fields) {
		if (field.getName().contains("$VALUES")) {
			valuesField = field;
			break;
		}
	}
	AccessibleObject.setAccessible(new Field[] { valuesField }, true);

	try {

		// 2. Copy it
		T[] previousValues = (T[]) valuesField.get(enumType);
		List<T> values = new ArrayList<T>(Arrays.asList(previousValues));

		// 3. build new enum
		T newValue = (T) makeEnum(enumType, // The target enum class
				enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED
				values.size(), new Class<?>[] {}, // could be used to pass
													// values to the enum
													// constuctor if needed
				new Object[] {}); // could be used to pass values to the
									// enum constuctor if needed

		// 4. add new value
		values.add(newValue);

		// 5. Set new values field
		setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));

		// 6. Clean enum cache
		cleanEnumCache(enumType);

	} catch (Exception e) {
		e.printStackTrace();
		throw new RuntimeException(e.getMessage(), e);
	}
}

/**
 * Add an enum instance to the enum class given as argument
 *
 * @param <T>      the type of the enum (implicit)
 * @param enumType the class of the enum to be modified
 * @param enumName the name of the new enum instance to be added to the class.
 */
@SuppressWarnings("unchecked")
public static <T extends Enum<?>> void addEnum(Class<T> enumType, String enumName, Class<?>[] additionalTypes, Object[] additionalValues) {

	// 0. Sanity checks
	if (!Enum.class.isAssignableFrom(enumType)) {
		throw new RuntimeException("class " + enumType + " is not an instance of Enum");
	}

	// 1. Lookup "$VALUES" holder in enum class and get previous enum instances
	Field valuesField = null;
	Field[] fields = enumType.getDeclaredFields();
	for (Field field : fields) {
		if (field.getName().contains("$VALUES")) {
			valuesField = field;
			break;
		}
	}
	AccessibleObject.setAccessible(new Field[] { valuesField }, true);

	try {

		// 2. Copy it
		T[] previousValues = (T[]) valuesField.get(enumType);
		List<T> values = new ArrayList<T>(Arrays.asList(previousValues));

		// 3. build new enum
		T newValue = (T) makeEnum(enumType, enumName, values.size(), additionalTypes, additionalValues);

		// 4. add new value
		values.add(newValue);

		// 5. Set new values field
		setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));

		// 6. Clean enum cache
		cleanEnumCache(enumType);

	} catch (Exception e) {
		throw new RuntimeException(e.getMessage(), e);
	}
}

private static enum TestEnum {
	a, b, c;
};

public static void main(String[] args) {

	// Dynamically add 3 new enum instances d, e, f to TestEnum
	addEnum(TestEnum.class, "d");
	addEnum(TestEnum.class, "e");
	addEnum(TestEnum.class, "f");

	// Run a few tests just to show it works OK.
	System.out.println(Arrays.deepToString(TestEnum.values()));
	// Shows : [a, b, c, d, e, f]

	addEnum(ResponseCode.class, "TESET", new Class[] { int.class, String.class }, new Object[] { 250, "二百五" });

	System.out.println(Arrays.deepToString(ResponseCode.values()));

	System.out.println(ResponseCode.valueOf("TESET").getDesc());
	System.out.println(ResponseCode.valueOf("TESET").getCode());

}

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java枚举的集中管理 的相关文章

  • OSGI - 处理捆绑包所需的第 3 方 JAR

    我刚刚开始 OSGI 开发 正在努力了解如何最好地处理依赖的 JAR 也就是说 如果我要创建一个捆绑包 我很可能需要使用一些第 3 方 JAR 当我创建要部署到 OSGI 的捆绑包 JAR 时 显然不包含这些第 3 方 JAR 因此该捆绑包
  • 如何禁用 Spring 日志记录 DEBUG 消息?

    我正在开发一个简单的桌面应用程序 不是网络应用程序 这是我的log4j properties log4j rootCategory INFO stdout log4j appender stdout org apache log4j Con
  • Java中如何做系统捷径跨平台集成?

    您可能知道 Mac OS X 中保存的快捷键是Cmd S在 Windows 上是Ctrl S 关闭应用程序的捷径是Cmd QWindows 是Alt F4 但问题是如何在 java 应用程序中执行这些操作 我是否需要找到我在应用程序中使用的
  • 为什么不在下一个 JVM 中删除类型擦除呢?

    Java 在 Java 5 中引入了泛型类型擦除 因此它们可以在旧版本的 Java 上运行 这是兼容性的权衡 我们已经失去了这种兼容性 1 https stackoverflow com questions 22610400 a progr
  • 在 eclipse indigo 中找不到 Window builder pro

    我读到 Eclipse Indigo 安装了 Window Builder Pro 插件 但我不知道它在哪里 文件 新建 项目没有给我选择 Window Builder Pro 的选项 如何找到它 您需要将此更新站点添加到 Eclipse
  • 如何为流数据创建 Flux/Publisher

    我正在使用轮询方法定期获取数据 新数据可能随时到达 我想向我的客户公开一个反应式接口 因此 我想创建一个发布者 Flux 它会在新数据可用时发布新数据并通知订阅者 我怎么做 我看到的所有 Flux 示例都是针对数据已知 可用的情况 实际上
  • 有人在实际应用程序中使用短和字节原始类型吗?

    我自 2004 年以来一直使用 Java 进行编程 主要是企业和 Web 应用程序 但我从来没有用过short or byte 而不是只是为了了解这些类型如何工作的玩具程序 即使在一个for loop100次 我们通常会选择int 我不记得
  • Hibernate/JPA 在启动时不验证数据库架构

    由于某种原因 hibernate 无法捕获诸如将实体映射到不存在的表之类的问题 我的 persistence xml 文件看起来像这样
  • 如何在MongoDb中保存Timestamp类型值 |爪哇

    从 Java 驱动程序中 我想在 MongoDb 中保存一个类似于下面 json 的文档 ts Timestamp 1421006159 4 我尝试过的选项 选项1 映射 doc new HashMap 1 doc put ts new B
  • Java 8 Arraylist 巨大容量(int) 实现

    我正在阅读文档了解如何ArrayListJava 中的 s 已增长 我不明白为什么hugeCapacity int minCapacity http grepcode com file repository grepcode com jav
  • 验证在子类上调用此方法时是否调用了重写的超类方法

    我将用这个例子来展示我的问题 我有一个带有方法的类foo 该类有一个重写此方法的子类 子类的方法调用超类的方法 我可以验证一下吗 我不想测试什么foo在超类中确实如此 我只需要验证它是否被调用 我知道重构可以有所帮助 优先考虑组合而不是继承
  • 为什么桌面 AES 文件 IO 与 Android AES 文件 IO 不兼容?

    我已将一个应用程序从 Android 移植到桌面 该应用程序使用 AES 加密一些私人数据 两个应用程序都能够加密和解密数据以供自己使用 但无法解密其他应用程序的数据 AES 密钥 IV 和算法是相同的 这两个应用程序之间的主要区别在于 a
  • Struts 2 中的 Java 应用程序可以管理多少个会话?

    我正在开发事务管理应用程序 并且正在使用 Struts2 我在内部使用了一个会话来设置和获取值 例如 ActionContext getContext getSession put string string 在应用程序中使用这样的会话是否
  • java.lang.String 无法转换为 org.json.simple.JSONObject simple-json

    我在尝试使用 google 的 simple json 解析简单的 json 时遇到奇怪的问题 这是我的代码 它不起作用 String s args 0 toString JSONObject json JSONObject new JSO
  • 封闭实例的匿名类

    我正在阅读 Joshua Bloch 的 Effective Java 第二版 目前我在第 22 项 它描述了内部类和嵌套类 但我无法理解他这句话的意思 匿名类具有封闭实例当且仅当它们发生时 在非静态上下文中 有人能给我一个代码示例并解释它
  • 从 Java 读取 /dev/input/js0

    我正在尝试阅读 dev input js0来自Java 但我不断得到 java io IOException Invalid argument at java io FileInputStream read0 Native Method a
  • 不要使用android内置的org.json

    我写了一个使用的库org json http json org A 来自 json org 假设 Android 使用相同的 在 android 中也称为org json B 只是它遗漏了一些相对关键的功能 现在我想做的是设置我的 grad
  • 使用 Wildfly 在 Jersey 上使用 @PersistenceUnit 注入 EntityManagerFactory

    我尝试使用 PersistenceUnit 注入 EntityManagerFactory 但它始终为空 我认为我的 persistence xml 没问题 因为我可以使用以下代码获取 EntityManager EntityManager
  • TextView 用字母打乱了我的话

    我的要求 创建 传入气泡 其宽度按内容排列 最大宽度为 90 我有这个标记
  • Java无限信号量

    想知道如何not使用信号量限制连接 或任何东西 所以你可能会想 这听起来很愚蠢 但是 它稍微简化了我的代码 因为它让我可以统一处理有限和无限的情况 请注意 我并不是在寻找有关如何编写类似内容的建议 if limited semaphore

随机推荐

  • Qt设置label的文字自动换行、高度随内容调整、上下可滚动

    Qt初学者 想要用label控件实现一个用于显示文字信息的文本框 要求文字自动换行 label高度随内容调整 上下可滚动 为了实现滚动 使用ScrollArea控件 将要显示文字的label放到这个ScrollArea里 然后设置Scrol
  • 控制台报错:failed to load resource: net:err_cert_date_invalid的解决办法

    原因 浏览器端屏蔽了不安全的连接 解决办法 1 打开检查页面里 Network 网络 2 双击name 名称 下红色报错的地方 会出现以下界面 3 点击高级 下面会出现提示 点击继续前往 不安全 4 回到之前的页面刷新 问题就解决了
  • Exception of type 'System.OutOfMemoryException' was thrown.

    OutOfMemoryException Exception of type System OutOfMemoryException was thrown 在装有4G物理内存的32位OS机器上内存不足 原因是 The common lang
  • array type has an incomplete element type

    一 错误详情 array type has an incomplete element type 二 错误分析 1 错误代码 int readInfo int B int n int findMax int B int n int m 2
  • 英伟达Tesla T4 显卡编解码能力测试

    显卡基本参数 Timestamp Fri Aug 27 10 04 12 2021 Driver Version 460 32 03 CUDA Version 11 2 Attached GPUs 8 FB Memory Total 151
  • 计算机网络【IP数据包首部的各个字段详解】

    文章目录 一 网络层简述 二 网络层首部 版本 首部长度 区分服务 总长度 三 网络层首部 标识 标志 片偏移 四 网络层首部 生存时间 协议 首部检验和 五 可选字段 填充字段 源IP 目标IP 六 总结 一 网络层简述 一个IP数据包的
  • Windows计划任务(手动执行脚本正常,定时执行不生效)

    ps 本公司是一家游戏公司 目前有一台win服务器上面搭建MySQL数据库 现在需要做MySQL数据库的备份然后上传到Linux服务器上 bat 脚本写好以后手动双击测试多遍正常上传备份文件 可每当计划任务去执行的时候往往出错 不执行上传L
  • 系统开发设计基础(二)

    删除
  • 信号的傅里叶分析之傅里叶级数

    1 为什么要进行傅里叶分析 信号分析方法主流方法有 1 时域分析 以冲激信号为基本信号 任意输入信号可分解为一系列冲激信号 2 频域分析 以正弦信号和虚指数信号为基本信号 将任意输入信号分解为一系列不同频率的正弦信号或者虚指数信号之和 独立
  • c语言入门-程序运行的过程

    目录 程序运行的过程 1 编译 预编译 编译 汇编 2 链接 1 段表的合并 2 符号表的合并和重定位 3 运行 预处理 define 宏实现计算 define和typedef define的替换规则 和 将参数插入代码中 带有副作用的宏
  • Qt信号槽connect用法整理

    本文整理了一些当前项目中使用的Qt5 6版本信号 槽connect新旧写法的比较 需要注意的问题 一 connect string based和functor based写法比较 1 1 概述 自Qt 5 0以来 Qt提供了两种C 信号槽c
  • Python读取csv文件

    导入pandas包并设置别名为pd import pandas as pd 读取csv格式文件并把格式设置为DataFrame格式 值1是路径可以用绝对路径 cd盘内读取 也可以用相对路径 此项目内读取 这里用的是相对路径 作用 把乱码格式
  • SpringBoot整合eureka简记

    Eureka是一个服务治理组件 它主要包括服务注册和服务发现 主要用来搭建服务注册中心 Eureka 是一个基于 REST 的服务 用来定位服务 进行中间层服务器的负载均衡和故障转移 Eureka是Netflix 公司开发的 Spring
  • 模拟电路设计(14)---三点式振荡器

    常用三点式振荡器 晶体三极管其增益适中 工作频带宽 体积小巧 实际电路设计中常用来构成简洁可靠的三点式LC振荡器 是各种振荡器的主流电路 其交流等效电路组态见下图 三点式振荡器交流等效电路 上图所示三点式LC振荡器的交流等效电路 与实际原理
  • 半桥LLC谐振变换器及同步整流MATLAB仿真(一)

    在开关电源中 LLC谐振变换器是最常见的DC DC变换器之一 LLC谐振电路早在上世纪80年代就已经提出 到如今仍有广泛的应用 可见其优越性 其优点表现在 1 LLC的开关器件能实现软开关 开关损耗小 2 效率高 功率密度大 LLC按结构的
  • Project窗口

    窗口概述 在此视图中 可访问和管理属于项目的资源 以下 Project窗口也称为Project浏览器 Project浏览器的左侧面板将项目的文件夹结构显示为层级列表 通过单击从列表中选择文件夹时 文件夹内容将显示在右侧面板中 可单击小三角形
  • 第4章 基于RFID的仓储管理系统的实现

    4 1 需求分析 目前 在国内外应用比较广泛的仓储管理系统都采用了条形码或RFID 与条形码识别系统相比 无线射频识别技术具有很多优势 因此研究最多的还是射频识别技术在仓储中的应用 RFID技术的应用可以改善目前仓库管理的现状的不足 根据对
  • 【数学计算】点乘/点积/内积/数量积/叉乘/外积/叉积/向量积

    序言 区分一下这几个概念 1 点乘 点乘 点积 内积 数量积 dot product inner product scalar product a x
  • perl 服务器上建立文件目录,Perl脚本修改过的文件上传到FTP服务器

    Perl脚本修改过的文件上传到FTP服务器 简介 本文假定你是 A familar和 A2 从本地电脑上传文件到远程FTP服务器时 我跑进上传一个文件 其中只有少数实际上改变了很多的问题 所以我决定与那些比较本地文件的时间戳远程文件 理论上
  • java枚举的集中管理

    java枚举的集中管理 一 产品中遇到的实际情况 枚举类泛滥 这个 这个 这个 这个 在 JDK 1 5 之前没有枚举类型 那时候一般用接口常量来替代 而使用 Java 枚举类型 enum 可以更贴近地表示这种常量 但是在项目中 就变成这样