集册 Java实例教程 查找具有兼容参数的可访问构造函数。

查找具有兼容参数的可访问构造函数。

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

447
查找具有兼容参数的可访问构造函数。
/**来自 n o w j a v a . c o m**/

/*

 * Copyright (c) 2007-2016 AREasy Runtime

 *

 * This library, AREasy Runtime and API for BMC Remedy AR System, is free software ("Licensed Software");

 * you can redistribute it and/or modify it under the terms of the GNU Lesser General Public

 * License as published by the Free Software Foundation; either version 2.1 of the License,

 * or (at your option) any later version.

 *

 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;

 * including but not limited to, the implied warranty of MERCHANTABILITY, NONINFRINGEMENT,

 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

 */

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Modifier;


public class Main{

    /**

     * <p>Find an accessible constructor with compatible parameters.

     * Compatible parameters mean that every method parameter is assignable from

     * the given parameters. In other words, it finds constructor that will take

     * the parameters given.</p>

     * <p/>

     * <p>First it checks if there is constructor matching the exact signature.

     * If no such, all the constructors of the class are tested if their signatures

     * are assignment compatible with the parameter types.

     * The first matching constructor is returned.</p>

     *

     * @param clazz          find constructor for this class

     * @param parameterTypes find method with compatible parameters

     * @return a valid Constructor object. If there's no matching constructor, returns <code>null</code>.

     */

    private static Constructor getMatchingAccessibleConstructor(

            Class clazz, Class[] parameterTypes) {

        // see if we can find the method directly

        // most of the time this works and it's much faster

        try {

            Constructor ctor = clazz.getConstructor(parameterTypes);

            try {

                ctor.setAccessible(true);

            } catch (SecurityException se) {

            }

            return ctor;


        } catch (NoSuchMethodException e) { /* SWALLOW */
        /*
         from nowjava 
        */

        }


        // search through all methods

        int paramSize = parameterTypes.length;

        Constructor[] ctors = clazz.getConstructors();

        for (int i = 0, size = ctors.length; i < size; i++) {

            // compare parameters

            Class[] ctorParams = ctors[i].getParameterTypes();

            int ctorParamSize = ctorParams.length;

            if (ctorParamSize == paramSize) {

                boolean match = true;

                for (int n = 0; n < ctorParamSize; n++) {

                    if (!MethodUtility.isAssignmentCompatible(

                            ctorParams[n], parameterTypes[n])) {

                        match = false;

                        break;

                    }

                }


                if (match) {

                    // get accessible version of method

                    Constructor ctor = getAccessibleConstructor(ctors[i]);

                    if (ctor != null) {

                        try {

                            ctor.setAccessible(true);

                        } catch (SecurityException se) {

                        }

                        return ctor;

                    }

                }

            }

        }


        return null;

    }

    /**

     * Returns a constructor with single argument.

     *

     * @param klass the class to be constructed

     * @return null if matching accessible constructor can not be found.

     * @see Class#getConstructor

     * @see #getAccessibleConstructor(java.lang.reflect.Constructor)

     */

    public static Constructor getAccessibleConstructor(Class klass,

            Class parameterType) {


        Class[] parameterTypes = { parameterType };

        return getAccessibleConstructor(klass, parameterTypes);


    }

    /**

     * Returns a constructor given a class and signature.

     *

     * @param klass          the class to be constructed

     * @param parameterTypes the parameter array

     * @return null if matching accessible constructor can not be found

     * @see Class#getConstructor

     * @see #getAccessibleConstructor(java.lang.reflect.Constructor)

     */

    public static Constructor getAccessibleConstructor(Class klass,

            Class[] parameterTypes) {


        try {

            return getAccessibleConstructor(klass

                    .getConstructor(parameterTypes));

        } catch (NoSuchMethodException e) {

            return (null);

        }


    }

    
展开阅读全文