invoke Constructor - Java Reflection

Java examples for Reflection:Constructor

Description

invoke Constructor

Demo Code

/*/*w  ww  . java 2 s  .com*/
 **        DroidPlugin Project
 **
 ** Copyright(c) 2015 Andy Zhang <zhangyong232@gmail.com>
 **
 ** This file is part of DroidPlugin.
 **
 ** DroidPlugin is free 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 3 of the License, or (at your option) any later version.
 **
 ** DroidPlugin is distributed in the hope that it will be useful,
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ** Lesser General Public License for more details.
 **
 ** You should have received a copy of the GNU Lesser General Public
 ** License along with DroidPlugin.  If not, see <http://www.gnu.org/licenses/lgpl.txt>
 **
 **/
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

public class Main{
    public static <T> T invokeConstructor(final Class<T> cls,
            Object... args) throws NoSuchMethodException,
            IllegalAccessException, InvocationTargetException,
            InstantiationException {
        args = Utils.nullToEmpty(args);
        final Class<?> parameterTypes[] = Utils.toClass(args);
        return invokeConstructor(cls, args, parameterTypes);
    }
    public static <T> T invokeConstructor(final Class<T> cls,
            Object[] args, Class<?>[] parameterTypes)
            throws NoSuchMethodException, IllegalAccessException,
            InvocationTargetException, InstantiationException {
        args = Utils.nullToEmpty(args);
        parameterTypes = Utils.nullToEmpty(parameterTypes);
        final Constructor<T> ctor = getMatchingAccessibleConstructor(cls,
                parameterTypes);
        if (ctor == null) {
            throw new NoSuchMethodException(
                    "No such accessible constructor on object: "
                            + cls.getName());
        }
        return ctor.newInstance(args);
    }
    public static <T> Constructor<T> getMatchingAccessibleConstructor(
            final Class<T> cls, final Class<?>... parameterTypes) {
        Validate.isTrue(cls != null, "class cannot be null");
        // see if we can find the constructor directly
        // most of the time this works and it's much faster
        try {
            final Constructor<T> ctor = cls.getConstructor(parameterTypes);
            MemberUtils.setAccessibleWorkaround(ctor);
            return ctor;
        } catch (final NoSuchMethodException e) { // NOPMD - Swallow
        }
        Constructor<T> result = null;
        /*
         * (1) Class.getConstructors() is documented to return Constructor<T> so as
         * long as the array is not subsequently modified, everything's fine.
         */
        final Constructor<?>[] ctors = cls.getConstructors();

        // return best match:
        for (Constructor<?> ctor : ctors) {
            // compare parameters
            if (MemberUtils.isAssignable(parameterTypes,
                    ctor.getParameterTypes(), true)) {
                // get accessible version of constructor
                ctor = getAccessibleConstructor(ctor);
                if (ctor != null) {
                    MemberUtils.setAccessibleWorkaround(ctor);
                    if (result == null
                            || MemberUtils.compareParameterTypes(
                                    ctor.getParameterTypes(),
                                    result.getParameterTypes(),
                                    parameterTypes) < 0) {
                        // temporary variable for annotation, see comment above (1)
                        @SuppressWarnings("unchecked")
                        final Constructor<T> constructor = (Constructor<T>) ctor;
                        result = constructor;
                    }
                }
            }
        }
        return result;
    }
    private static <T> Constructor<T> getAccessibleConstructor(
            final Constructor<T> ctor) {
        Validate.isTrue(ctor != null, "constructor cannot be null");
        return MemberUtils.isAccessible(ctor)
                && isAccessible(ctor.getDeclaringClass()) ? ctor : null;
    }
    private static boolean isAccessible(final Class<?> type) {
        Class<?> cls = type;
        while (cls != null) {
            if (!Modifier.isPublic(cls.getModifiers())) {
                return false;
            }
            cls = cls.getEnclosingClass();
        }
        return true;
    }
}

Related Tutorials