返回具有给定名称和参数的可访问方法(即可以通过反射调用的方法)。
/******************************************************************************* * 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;/** n o w j a v a . c o m - 时 代 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{ /** * <p> * Return an accessible method (that is, one that can be invoked via * reflection) with given name and parameters. If no such method can be * found, return <code>null</code>. This is just a convenient wrapper for * {@link #getAccessibleMethod(Method method)}. * </p> * * @param cls * get method from this class * @param methodName * get method with this name * @param parameterTypes * with these parameters types * @return The accessible method */ public static Method getAccessibleMethod(Class<?> cls, String methodName, Class<?>... parameterTypes) { try { return getAccessibleMethod(cls.getMethod(methodName, parameterTypes));/** n o w j a v a . c o m - 时 代 Java 提供 **/ } catch (NoSuchMethodException e) { return (null); } } /** * <p> * Return an accessible method (that is, one that can be invoked via * reflection) that implements the specified Method. If no such method can * be found, return <code>null</code>. * </p> * * @param method * The method that we wish to call * @return The accessible method */ public static Method getAccessibleMethod(Method method) { if (!MemberUtils.isAccessible(method)) { return null; } // If the declaring class is public, we are done Class<?> cls = method.getDeclaringClass(); if (Modifier.isPublic(cls.getModifiers())) { return method; } String methodName = method.getName(); Class<?>[] parameterTypes = method.getParameterTypes(); // Check the implemented interfaces and subinterfaces method = getAccessibleMethodFromInterfaceNest(cls, methodName, parameterTypes); // Check the superclass chain if (method == null) { method = getAccessibleMethodFromSuperclass(cls, methodName, parameterTypes); } return method; } /** * <p> * Return an accessible method (that is, one that can be invoked via * reflection) that implements the specified method, by scanning through all * implemented interfaces and subinterfaces. If no such method can be found, * return <code>null</code>. * </p> * * <p> * There isn't any good reason why this method must be private. It is * because there doesn't seem any reason why other classes should call this * rather than the higher level methods. * </p> * * @param cls * Parent class for the interfaces to be checked * @param methodName * Method name of the method we wish to call * @param parameterTypes * The parameter type signatures * @return the accessible method or <code>null</code> if not found */ private static Method getAccessibleMethodFromInterfaceNest( Class<?> cls, String methodName, Class<?>... parameterTypes) { Method method = null; // Search up the superclass chain for (; cls != null; cls = cls.getSuperclass()) { // Check the implemented interfaces of the parent class Class<?>[] interfaces = cls.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { // Is this interface public? if (!Modifier.isPublic(interfaces[i].getModifiers())) { continue; } // Does the method exist on this interface? try { method = interfaces[i].getDeclaredMethod(methodName, parameterTypes); } catch (NoSuchMethodException e) { /* * Swallow, if no method is found after the loop then this * method returns null. */ } if (method != null) { break; } // Recursively check our parent interfaces method = getAccessibleMethodFromInterfaceNest( interfaces[i], methodName, parameterTypes); if (method != null) { break; } } } return method; }