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