查找可访问的方法,并包括所有继承的接口。
/******************************************************************************* * Copyright (c) 2011 MadRobot. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Elton Kent - initial API and implementation ******************************************************************************/ import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.lang.reflect.InvocationTargetException;/**来自 nowjava.com - 时 代 Java**/ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; public class Main{ private static Map declaredMethodCache = Collections .synchronizedMap(new WeakHashMap()); /** * *Find accessible method and include any inherited interfaces as well. *<p> * Its a little slow when compared to * {@link MethodUtils#findAccessibleMethod(Class, String, Class...)} *</p> * * @param start * @param methodName * @param argCount * number of arguments * @param argumentTypes * list of argument types. If null the method is determined based * on <code>argCount</code> * @return */ public static Method findAccessibleMethodIncludeInterfaces(Class start, String methodName, int argCount, Class argumentTypes[]) {/*n o w j a v a . c o m 提 供*/ if (methodName == null) { return null; } // For overriden methods we need to find the most derived version. // So we start with the given class and walk up the superclass chain. Method method = null; for (Class cl = start; cl != null; cl = cl.getSuperclass()) { Method methods[] = MethodUtils.getPublicDeclaredMethods(cl); for (int i = 0; i < methods.length; i++) { method = methods[i]; if (method == null) { continue; } // make sure method signature matches. Class params[] = method.getParameterTypes(); if (method.getName().equals(methodName) && params.length == argCount) { if (argumentTypes != null) { boolean different = false; if (argCount > 0) { for (int j = 0; j < argCount; j++) { if (params[j] != argumentTypes[j]) { different = true; continue; } } if (different) { continue; } } } return method; } } } method = null; // Now check any inherited interfaces. This is necessary both when // the argument class is itself an interface, and when the argument // class is an abstract class. Class ifcs[] = start.getInterfaces(); for (int i = 0; i < ifcs.length; i++) { // Note: The original implementation had both methods calling // the 3 arg method. This is preserved but perhaps it should // pass the args array instead of null. method = findAccessibleMethodIncludeInterfaces(ifcs[i], methodName, argCount, null); if (method != null) { break; } } return method; } /** * Get the methods declared as public within the class * * @param clz * class to find public methods * @return */ public static synchronized Method[] getPublicDeclaredMethods(Class clz) { // Looking up Class.getDeclaredMethods is relatively expensive, // so we cache the results. Method[] result = null; // if(!ReflectUtil.isPackageAccessible(clz)){ // return new Method[0]; // } final Class fclz = clz; Reference ref = (Reference) declaredMethodCache.get(fclz); if (ref != null) { result = (Method[]) ref.get(); if (result != null) {