每一個類被加載後(類文件常量池), 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; }