package michael.spica.tool.lang;import michael.spica.tool.common.Strings;import java.util.Arrays;
import java.util.List;
import java.util.Map;/*** 枚举工具类* <p>* Created by michael on 2015-11-26*/
public class Enums extends EnumSupport {/*** 根据字符串名称(忽略大小写)获取对应枚举中的属性** @param <T>* @param name  字符串* @param clazz 枚举类* @return*/public static <T extends Enum<?>> T get(String name, Class<T> clazz) {if (!clazz.isEnum()) {throw new IllegalArgumentException(clazz + " not an enumeration class.");} else {Enum[] values = clazz.getEnumConstants();Enum[] arr = values;for (int i = 0; i < values.length; ++i) {Enum<?> value = arr[i];if (Strings.equalsIgnoreCase(value.name(), name)) {return ((T) value);}}return null;}}/*** 根据字符串名称(忽略大小写)获取对应枚举中的属性** @param <T>* @param name         字符串* @param clazz        枚举类* @param defaultValue 默认值* @return*/public static <T extends Enum<?>> T get(String name, Class<T> clazz, T defaultValue) {Enum<?> value = get(name, clazz);return (T) (value == null ? defaultValue : value);}/*** 将Enum转换成List** @param <T>* @param clazz* @return*/public static <T extends Enum<?>> List<T> toList(Class<T> clazz) {return Arrays.asList(clazz.getEnumConstants());}/*** 将Enum转换成Map** @param <T>* @param clazz* @param methodName Enum类的指定的方法,当methodName=null时,默认为Enum.name方法<br>*                   e.g: <br>*                   model.addAttribute("tradeStatusMap", Enums.toMap(Enums.TradeStatus.class,"getValue"));<br>*                   ${tradeStatusMap[key].desc},key为入参methodName的值* @return*/public static <T extends Enum<?>> Map<Object, T> toMap(Class<T> clazz, String methodName) {return enumConstantDirectory(clazz, methodName);}
}
package michael.spica.tool.lang;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;/*** Created by michael on 2015-11-26.*/
public abstract class EnumSupport extends EnumSupportWithDynamic {public EnumSupport() {}protected static <T extends Enum<?>> Map<Object, T> enumConstantDirectory(Class<T> clazz, String methodName) {Map<Object, T> directory = null;if (directory == null) {T[] universe = getEnumConstantsShared(clazz);if (universe == null){throw new IllegalArgumentException(clazz.getName() + " is not an enum type.");}Map<Object, T> m = new HashMap<Object, T>(2 * universe.length);for (T constant : universe)try {Object key = null;if (methodName != null && methodName.trim().length() > 0) {Method method = constant.getClass().getMethod(methodName);key = method.invoke(constant);} else {key = (constant).name(); // 默认KEY为ENUM的NAME}m.put(key, constant);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}directory = m;}return directory;}private static <T extends Enum<?>> T[] getEnumConstantsShared(Class<T> clazz) {T[] enumConstants = null;if (enumConstants == null) {if (!clazz.isEnum())return null;try {final Method values = clazz.getMethod("values");AccessController.doPrivileged((PrivilegedAction<Void>) () -> {values.setAccessible(true);return null;});T[] temporaryConstants = (T[]) values.invoke(null);enumConstants = temporaryConstants;} catch (InvocationTargetException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();}}return enumConstants;}
}
package michael.spica.tool.lang;import org.apache.commons.lang3.StringUtils;
import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;/*** 枚举动态支持(即:程序运行时动态增加枚举类型)* <p>* Created by michael on 2015-11-26.*/
public abstract class EnumSupportWithDynamic {public EnumSupportWithDynamic() {}private static ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();public static <T extends Enum<?>> void addEnum(Class<T> enumClass, List<String> enumNames) {enumNames.stream().filter(enumName -> StringUtils.isNotEmpty(enumName)).forEach(enumName -> addEnum(enumClass, enumName));}public static <T extends Enum<?>> void addEnum(Class<T> enumClass, String... enumNames) {Stream.of(enumNames).filter(enumName -> StringUtils.isNotEmpty(enumName)).forEach(enumName -> addEnum(enumClass, enumName));}/*** 添加枚举** @param enumClass 枚举类* @param enumName  枚举名* @param <T>*/public static <T extends Enum<?>> void addEnum(Class<T> enumClass, String enumName) {if (StringUtils.isEmpty(enumName)) {throw new RuntimeException("Enumeration name cannot be empty.");}// 0. Sanity checksif (!Enum.class.isAssignableFrom(enumClass)) {throw new RuntimeException("class " + enumClass + " is not an instance of Enum.");}// 1. Lookup "$VALUES" holder in enum class and get previous enum instancesField valuesField = null;Field[] fields = enumClass.getDeclaredFields();for (Field field : fields) {if (field.getName().contains("$VALUES")) {valuesField = field;break;}}AccessibleObject.setAccessible(new Field[]{valuesField}, true);try {// 2. Copy itT[] previousValues = (T[]) valuesField.get(enumClass);List values = new ArrayList(Arrays.asList(previousValues));// 3. build new enumT newValue = (T) makeEnum(enumClass, // The target enum classenumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDEDvalues.size(),new Class[]{}, // can be used to pass values to the enum constuctornew Object[]{}); // can be used to pass values to the enum constuctor// 4. add new valuevalues.add(newValue);// 5. Set new values fieldsetFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumClass, 0)));// 6. Clean enum cachecleanEnumCache(enumClass);} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage(), e);}}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));}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 void setFailsafeFieldValue(Field field,Object target,Object value) throws NoSuchFieldException, IllegalAccessException {// let's make the field accessiblefield.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 fieldField modifiersField = Field.class.getDeclaredField("modifiers");modifiersField.setAccessible(true);int modifiers = modifiersField.getInt(field);// blank out the final bit in the modifiers intmodifiers &= ~Modifier.FINAL;modifiersField.setInt(field, modifiers);FieldAccessor fa = reflectionFactory.newFieldAccessor(field, false);fa.set(target, value);}/*** 清除枚举缓存** @param enumClass* @throws NoSuchFieldException* @throws IllegalAccessException*/private static void cleanEnumCache(Class<?> enumClass) throws NoSuchFieldException, IllegalAccessException {blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK 1.5/6blankField(enumClass, "enumConstants"); // IBM JDK}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;}}}
}

java枚举处理工具相关推荐

  1. 你一定需要知道的高阶JAVA枚举特性!

    JAVA枚举,比你想象中功能还要强大! 我经常发现自己在Java中使用枚举来表示某个对象的一组值. 在编译时确定类型可以具有什么值的能力是一种强大的能力,它为代码提供了结构和意义. 当我第一次了解枚举 ...

  2. Java枚举原来还能这么用

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 前言 相信不少java开发者写过状态变更的业务,比如订单流程.请假流程等等.一般会搞一个状态 ...

  3. java 注解 enum_13 Java枚举和注解

    Java枚举 在某些情况下,一个类的对象是有限而且固定的.例如季节类,只能有 4 个对象. 当类的对象是有限时,就应该使用枚举,而不使用普通类.(枚举对象是单例模式) 枚举的属性 实现接口的枚举类 例 ...

  4. 学妹问我Java枚举类与注解,我直接用这个搞定她!

    很多人问我学妹长什么样,不多说 上图吧! 学妹问我Java枚举类与注解,我直接一篇文章搞定! 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举 ...

  5. java 设置两个方法互斥_分享两个操作Java枚举的实用方法

    1. 前言 Java枚举在开发中是非常实用的.今天再来分析几个小技巧并且回答一些同学的的疑问.首先要说明的是我的枚举建立在以下的范式之中: 枚举统一接口范式 2. 如何把枚举值绑定的下拉列表 这种场景 ...

  6. java枚举类中字段有没有必要加final____枚举类字段 Field ‘xxx‘ may be ‘final‘

    java枚举类中字段有没有必要加final 今天在写一个系统统一返回码的枚举类时候,突然想到一个问题,当不小心手抖给枚举类自动生成了set方法,而恰巧在用的地方不小心用了set方法,从而修改了code ...

  7. java枚举类型特点_必须了解的高阶JAVA枚举特性!

    免费资源网,https://freexyz.cn/ JAVA枚举,比你想象中还要有用! 我经常发现自己在Java中使用枚举来表示某个对象的一组潜在值. 在编译时确定类型可以具有什么值的能力是一种强大的 ...

  8. Java枚举(Enum)类型的基本介绍与原理探求

    Enum枚举类型 Enum的全写是Enumeration,这个词的翻译是列举.逐条陈述.细目.在程序语言中,枚举类型是一种特殊的数据类型(常用的数据类型比如字符串.整型),这种数据类型的变量值限定在固 ...

  9. Java 枚举类型的应用

    实验十一 Java 枚举类型的应用 一.实验目的 1 .掌握枚举的定义方式. 2 .掌握 enum 关键字与 Enum 类的关系. 二.实验学时 2 学时 三.实验类型 验证性实验 四.实验需求 1 ...

  10. Java学习路线图,内附完整Java自学视频教程+工具经验

    Java学习路线图更新日志:         增加视频<2016最新视频struts2> 密码:vhfp(2016.11.10) 增加视频<6天玩转mysql视频> 密码:a8 ...

最新文章

  1. 分享阿里云SLB-负载均衡的实现基本原理架构
  2. Android开源项目分类汇总-转载
  3. Vue开发跨端应用(四)electron发布web应用并打包app
  4. mysql 编码分层_【平台开发】— 5.后端:代码分层
  5. Chrome插件-新浪微博阅读器
  6. 玩玩Xamarin Evolve 2016带来的新特性(一)-iOS Simulator(for Windows)
  7. Python复制数据
  8. [211渣硕] 腾讯/阿里/携程 详细NLP算法实习 面经
  9. http web 返回码概念
  10. java io流不关闭_Java IO流关闭问题的深入研究
  11. Json格式类的转换相关代码--转载
  12. (并查集) Wireless Network --POJ --2236
  13. 科普贴:示波器的组成
  14. 现在90后程序员有必要考证吗?
  15. RK3399 eMMC硬件设计要点
  16. 无线服务器功能,无线自组织互联网的用户管理——Radius服务器的功能设计与实现...
  17. 机器人无限火力无限e符文_无限火力快乐玩法:无限击飞机器人
  18. DPU芯片企业中科驭数加入龙蜥社区,构建异构算力生态
  19. python vlookup_多条件python中的Vlookup
  20. 云队友丨人与人之间的差距,在于自主性的不同

热门文章

  1. 全球上市公司和VC们如何布局元宇宙,是资本盛宴还是炒作概念?
  2. 记2012.12.20北京CISSP考试通过-“末日”前终于拿到“船票”
  3. windowsXPsp3恢复桌面IE图标
  4. 华硕ASUS路由器AC86U无线掉线解决方法
  5. 全民投资人游戏服务器维护,欢乐园《全民仙战》3月5日14时合服公告
  6. Mac工具 shimo 无法正常使用(macOS 系统版本问题)
  7. OpenWRT 迅雷远程下载设置
  8. 高效笔记法——康奈尔笔记
  9. Kalman滤波器参数分析
  10. github snap android,轻量级的viewpager指示器