Java Class New Instance newInstance(Class cls, Object... args)

Here you can find the source of newInstance(Class cls, Object... args)

Description

Creates a new instance matching possible constructors with provided args.

License

Apache License

Parameter

Parameter Description
cls class to instantiate
args arguments of the constructor
T type of the instance

Exception

Parameter Description
NoSuchMethodException if a matching method is not found.
IllegalAccessException if this Constructor objectis enforcing Java language access control and the underlyingconstructor is inaccessible.
InstantiationException if the class that declares theunderlying constructor represents an abstract class.
InvocationTargetException if the underlying constructorthrows an exception.

Return

new instance

Declaration

public static <T> T newInstance(Class<T> cls, Object... args) throws NoSuchMethodException,
        IllegalAccessException, InvocationTargetException, InstantiationException 

Method Source Code

//package com.java2s;
//License from project: Apache License 

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationTargetException;

import java.util.HashMap;

import java.util.Map;

public class Main {
    private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
    private static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS = new HashMap<>();

    /**/*from w  ww.j  a  v a  2  s  .c o m*/
     * Creates a new instance matching possible constructors with provided args.
     *
     * @param cls  class to instantiate
     * @param args arguments of the constructor
     * @param <T>  type of the instance
     * @return new instance
     * @throws NoSuchMethodException     if a matching method is not found.
     * @throws IllegalAccessException    if this {@code Constructor} object
     *                                   is enforcing Java language access control and the underlying
     *                                   constructor is inaccessible.
     * @throws InstantiationException    if the class that declares the
     *                                   underlying constructor represents an abstract class.
     * @throws InvocationTargetException if the underlying constructor
     *                                   throws an exception.
     */
    public static <T> T newInstance(Class<T> cls, Object... args) throws NoSuchMethodException,
            IllegalAccessException, InvocationTargetException, InstantiationException {
        Constructor<T> declaredConstructor = args.length == 0 ? getConstructor(cls) : getConstructor(cls, args);
        boolean accessible = declaredConstructor.isAccessible();
        if (accessible) {
            return declaredConstructor.newInstance(args);
        } else {
            declaredConstructor.setAccessible(true);
            try {
                return declaredConstructor.newInstance(args);
            } finally {
                declaredConstructor.setAccessible(accessible);
            }
        }
    }

    /**
     * Retrieve the constructor of a class for given argument values.
     *
     * @param cls  class to retrieve the constructor from
     * @param args argument values
     * @param <T>  type to retrieve the constructor from
     * @return matching constructor for given argument values
     * @throws NoSuchMethodException if a matching method is not found.
     */
    public static <T> Constructor<T> getConstructor(Class<T> cls, Object... args) throws NoSuchMethodException {
        Class<?>[] argsTypes = toClass(args);
        return getConstructor(cls, argsTypes);
    }

    /**
     * Retrieve the constructor of a class for given argument types.
     *
     * @param cls       class to retrieve the constructor from
     * @param argsTypes argument types
     * @param <T>       type to retrieve the constructor from
     * @return matching constructor for given argument values
     * @throws NoSuchMethodException if a matching method is not found.
     */
    public static <T> Constructor<T> getConstructor(Class<T> cls, Class<?>... argsTypes)
            throws NoSuchMethodException {
        if (argsTypes == null || argsTypes.length == 0) {
            return cls.getDeclaredConstructor();
        }

        try {
            return cls.getDeclaredConstructor(argsTypes);
        } catch (NoSuchMethodException e) {
            for (Constructor<?> constructor : cls.getDeclaredConstructors()) {
                if (isMatchingConstructor(constructor, argsTypes)) {
                    return (Constructor<T>) constructor;
                }
            }
            throw e;
        }
    }

    /**
     * Converts an array of {@code Object} into an array of {@code Class} objects.
     * <p>If any of these objects is null, a null element will be inserted into the array.</p>
     * <p>This method returns {@code null} for a {@code null} input array.</p>
     *
     * @param array an {@code Object} array
     * @return a {@code Class} array, {@code null} if null array input
     */
    public static Class<?>[] toClass(Object... array) {
        if (array == null) {
            return null;
        } else if (array.length == 0) {
            return EMPTY_CLASS_ARRAY; // NOPMD MethodReturnsInternalArray
        }
        Class<?>[] classes = new Class[array.length];
        for (int i = 0; i < array.length; i++) {
            classes[i] = (array[i] == null) ? null : array[i].getClass();
        }
        return classes;
    }

    private static boolean isMatchingConstructor(Constructor<?> constructor, Class<?>[] argsTypes) {
        Class<?>[] parameterTypes = constructor.getParameterTypes();
        if (parameterTypes.length != argsTypes.length) {
            return false;
        }

        boolean match = true;
        for (int i = 0; i < parameterTypes.length; i++) {
            parameterTypes[i] = wrapPrimitive(parameterTypes[i]);
            if (argsTypes[i] != null) { // NOPMD ConfusingTernary
                if (!parameterTypes[i].isAssignableFrom(argsTypes[i])) {
                    match = false;
                    break;
                }
            } else if (parameterTypes[i].isPrimitive()) {
                match = false;
                break;
            }
        }
        return match;
    }

    /**
     * Wrap given class to it's primitive class if it's matching a primitive class.
     *
     * @param clazz primitive class or not
     * @param <T>   type of class
     * @return class or primitive class
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> wrapPrimitive(Class<T> clazz) {
        return clazz.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(clazz) : clazz;
    }
}

Related

  1. newInstance(Class clazz)
  2. newInstance(Class clazz, Class[] argumentTypes, Object[] arguments)
  3. newInstance(Class clazz, Class[] parameterTypes, Object[] initargs)
  4. newInstance(Class cls)
  5. newInstance(Class cls)
  6. newInstance(Class clz, Class argType, K arg)
  7. newInstance(Class componentType, int size)
  8. newInstance(Class elementType, int len)
  9. newInstance(Class klass)