根据code获取enum对象 (enumHelper.translate方法解读、Accessible解读)

1.根据Enum的code取出enum对象,看到一个enumHelper.translate方法

 public static <T extends Enum<T>> T translate(Class<T> clazz, String code) {
      try {
         // //通过class类对象获取名为getCode方法,(getMethod和getDeclaredMethod的区别)
         Method m = clazz.getDeclaredMethod("getCode");  
         // 根据class对象获取所有enum对象,构建迭代器
         Iterator i$ = inspectConstants(clazz).iterator();
         // 迭代,当code与enum对象getcode方法获取到的code相等时,返回当前enume对象
         while(i$.hasNext()) {
            T t = (Enum)i$.next();
            if (code.equals(m.invoke(t))) {
               return t;
            }
         }
      } catch(){}//异常处理

      LOGGER.debug("failed to translate code {} into object of type {}", code, clazz);
      return null;
   }

(这里先不说设置“getcode”方法的局限性,因为是compa的封装,满足使用即可。)

可以看到传参为Enum的Class类对象,和code。其中Class类的作用是运行时提供或获得某个对象的类型信息,和C++中的typeid()函数类似,这些信息也可用于反射。查看inspectConstants(clazz)方法:

   public static <T extends Enum<T>> List<T> inspectConstants(Class<T> clazz) {
     // 返回的是List对象,包含class对象中所有的enum对象
     return new ArrayList(Arrays.asList(clazz.getEnumConstants()));
   }

class的getEnumConstants很好,当enum对象向上转型之Enum时,我们无法再通过values()方法获取单独的enum对象,此时我们可以通过实例的Class类的getEnumConstants方法获取所有enum对象。

    /*   
     * @since 1.5
     */ 
   public T[] getEnumConstants() {
        T[] values = getEnumConstantsShared();
        return (values != null) ? values.clone() : null;
    }
    T[] getEnumConstantsShared() {
        if (enumConstants == null) {
            if (!isEnum()) return null;
            try {
                // 采用的仍然是values方法,并setAccessible(true),跳过java的安全校验
                final Method values = getMethod("values");
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                                values.setAccessible(true);
                                return null;
                            }
                        });
                @SuppressWarnings("unchecked")
                T[] temporaryConstants = (T[])values.invoke(null);
                enumConstants = temporaryConstants;
            }
            // These can happen when users concoct enum-like classes
            // that don't comply with the enum spec.
            catch (InvocationTargetException | NoSuchMethodException |
                   IllegalAccessException ex) { return null; }
        }
        return enumConstants;
    }

最终底层仍然是通过values方法,跳过java的安全机制校验,Accessible默认为false,一般情况下,我们在设置Field或执行Constructor时,务必要设置Accessible为true,这并不仅仅是因为操作习惯的问题,还是在为我们系统 的性能考虑,经过测试,在大量的反射情况下, 设置Accessible为true可以提升性能20倍以上。

这里可参考一位博主的研究:https://blog.csdn.net/lexang1/article/details/49642245

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值