集册 Java实例教程 查找可访问的方法,并包括所有继承的接口。

查找可访问的方法,并包括所有继承的接口。

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

408
查找可访问的方法,并包括所有继承的接口。

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

 * 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) {

  
展开阅读全文