Java Reflection Constructor Get getConstructor(final Class clazz, final Object... objs)

Here you can find the source of getConstructor(final Class clazz, final Object... objs)

Description

Returns a constructor that contains objs as arguments.

License

Apache License

Parameter

Parameter Description
clazz class on which we are searching the constructor
T type of the class searched
objs list of arguments of the constructor

Exception

Parameter Description
NoSuchMethodException when the constructor with args does not exist or isambiguous

Return

a constructor with the arguments in objs

Declaration

@SuppressWarnings("unchecked")
public static <T> Constructor<T> getConstructor(final Class<T> clazz, final Object... objs)
        throws NoSuchMethodException 

Method Source Code


//package com.java2s;
/*/*from w ww.  j  a  v  a 2  s .  c o  m*/
 * Copyright 2002-2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.lang.reflect.Constructor;

import java.lang.reflect.Modifier;

import java.util.HashMap;
import java.util.Map;

public class Main {
    private static Map<Class<?>, Class<?>> primitiveToWrapperType = new HashMap<Class<?>, Class<?>>();

    /**
     * Returns a constructor that contains {@code objs} as arguments.
     *
     * <p> We could not do something like {@code clazz.getConstructor(objs.class())} because that
     * would require casting all the passed arguments to the exact parameter types of the desired
     * constructor.
     *
     * @param clazz class on which we are searching the constructor
     * @param <T>   type of the class searched
     * @param objs  list of arguments of the constructor
     * @return a constructor with the arguments in {@code objs}
     * @throws NoSuchMethodException when the constructor with {@code args} does not exist or is
     *                               ambiguous
     */
    @SuppressWarnings("unchecked")
    public static <T> Constructor<T> getConstructor(final Class<T> clazz, final Object... objs)
            throws NoSuchMethodException {
        Constructor<T> ret = null;
        for (final Constructor<?> classConstructor : clazz.getDeclaredConstructors()) {
            if (isMatchingConstructor(classConstructor, objs)) {
                if (ret != null) {
                    // We had already found a constructor, so this is ambiguous
                    throw new IllegalArgumentException(
                            "Ambiguity in the constructors for " + clazz.getName() + ".");
                }

                // This unsafe cast is guaranteed to be correct by Class#getConstructors()
                ret = (Constructor<T>) classConstructor;
            }
        }

        if (ret != null) {
            return ret;
        }

        // Not found
        throw new NoSuchMethodException("Couldn't find constructor for class " + clazz.getName());
    }

    /**
     * Returns true if objects in {@code objs} are eligible to be passed to {@code classConstructor}.
     */
    private static boolean isMatchingConstructor(final Constructor<?> classConstructor, final Object... objs) {

        if (Modifier.isPrivate(classConstructor.getModifiers())) {
            return false;
        }

        final Class<?>[] parameterTypes = classConstructor.getParameterTypes();
        if (parameterTypes.length != objs.length) {
            return false;
        }

        for (int i = 0; i < objs.length; ++i) {
            Class<?> parameterType = parameterTypes[i];

            // If the parameter is a primitive, we need to get the boxed equivalent type
            if (parameterType.isPrimitive()) {
                parameterType = wrapPrimitive(parameterType);
            }

            // Check if parameter type matches
            if (!parameterType.isInstance(objs[i])) {
                return false;
            }
        }

        return true;
    }

    /**
     * Given a primitive type, returns its boxed equivalent. For instance, given {@code int}, returns
     * {@code Integer}.
     *
     * @param parameterType the primitive type
     * @return the boxed equivalent
     */
    private static Class<?> wrapPrimitive(final Class<?> parameterType) {
        return primitiveToWrapperType.get(parameterType);
    }
}

Related

  1. getConstructor(final Class clazz, final Class[] paramTypes)
  2. getConstructor(final Class valueClass, final Class parameter)
  3. getConstructor(final Class clazz, final Class... parametertypes)
  4. getConstructor(final Class clazz, final Class... parameterTypes)
  5. getConstructor(final Class clazz, final Object... constructorArgs)
  6. getConstructor(final Class instantiableClass, final Class... classes)
  7. getConstructor(String className, Class... argClasses)
  8. getConstructor(String cls_name, Class[] param_cls)
  9. getConstructor(String string, Class... types)