每一个类被加载后(类文件常量池), JVM就会为该类生成一个对应的 Class 对象(运行时常量池), 经过该 Class 对象就能够访问到 JVM 中的这个类 。java
Java 程序中得到Class 对象一般有以下三种方式:
1. 使用 Class 的 forName() 静态方法
2. 调用某个类的 class 属性 (无须调用方法, 性能更好)
3. 调用某个对象的 getClass() 方法数组
每次须要获取Class的对象时都使用Class.forName方法,或者在须要调用Class对象上的方法时都调用getDeclaredMethod(String name, Class<?>... parameterTypes)或getMethod(String name, Class<?>... parameterTypes)方法获取Method对象,再调用其上的invoke(Object obj, Object... args)方法。缓存
这里存在两个容易形成性能损耗的地方:函数
public Method[] getMethods() throws SecurityException { checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return copyMethods(privateGetPublicMethods()); } public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); if (method == null) { throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); } return method; } private static Method searchMethods(Method[] methods, String name, Class<?>[] parameterTypes) { Method res = null; String internedName = name.intern(); for (int i = 0; i < methods.length; i++) { Method m = methods[i]; if (m.getName() == internedName && arrayContentsEq(parameterTypes, m.getParameterTypes()) && (res == null || res.getReturnType().isAssignableFrom(m.getReturnType()))) res = m; } return (res == null ? res : getReflectionFactory().copyMethod(res)); }
一般: 将须要的反射的结果给缓存下来,避免屡次对类(方法、属性)信息屡次加载类信息并full查询,精确指定查找方式效率高于遍历查找。性能
public static String getValue(String property, Object o) { String res = ""; try { Method m = o.getClass().getMethod("get" + toFirstUp(property)); Object value = m.invoke(o); res = (value == null ? "" : value.toString()); } catch (Exception e) { logger.error(e, "getValue err"); } return res; } public static void setValue(String value, String property, Object o) { try { Method[] ms = o.getClass().getMethods(); for (Method m : ms) { if (m.getName().equals("set" + toFirstUp(property))) { m.invoke(o, new Object[] { value }); break; } } } catch (Exception e) { logger.error(e, "setValue err"); } } public static List<ValidateResult> validateAll(BaseValidate v) throws Exception { List<ValidateResult> list = new ArrayList<ValidateResult>(); Field[] fields = v.getClass().getDeclaredFields(); Map<Class, BaseVal> valMap = BaseVal.getValMap(); for (Field f : fields) { f.setAccessible(true); Annotation[] as = f.getAnnotations(); if (as != null && as.length > 0) { for (Annotation a : as) { BaseVal val = valMap.get(a.annotationType()); if (val != null) { ValidateResult result = val.validate(f.get(v), f, a); if (!result.isSucc()) { list.add(result); } } } } } return list; }