集册 Java实例教程 返回具有给定名称和参数的可访问方法(即可以通过反射调用的方法)。

返回具有给定名称和参数的可访问方法(即可以通过反射调用的方法)。

欢马劈雪     最近更新时间:2020-01-02 10:19:05

313
返回具有给定名称和参数的可访问方法(即可以通过反射调用的方法)。

/*******************************************************************************

 * 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

 ******************************************************************************//** 时代Java公众号 - nowjava.com 提 供 **/

import java.lang.ref.Reference;

import java.lang.ref.SoftReference;

import java.lang.reflect.InvocationTargetException;

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,//from NowJava.com - 时  代  Java

            String methodName, Class<?>... parameterTypes) {

        try {

            return getAccessibleMethod(cls.getMethod(methodName,

                    parameterTypes));

        } 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;

    }

    
展开阅读全文