一、前言
通过apache的开源包commons-beanutils(1.8.3)中的org.apache.commons.beanutils.ConstructorUtils构成函数工具类,可以通过映射类构成函数java.lang.reflect.Constructor实现对象实例化invokeConstructor(对象实例化新方式)、获取类公共的构成函数getAccessibleConstructor等
二、源码说明
package org.apache.commons.beanutils;@b@@b@import java.lang.reflect.Constructor;@b@import java.lang.reflect.InvocationTargetException;@b@import java.lang.reflect.Modifier;@b@@b@public class ConstructorUtils@b@{@b@ private static final Class[] EMPTY_CLASS_PARAMETERS = new Class[0];@b@ private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];@b@@b@ public static Object invokeConstructor(Class klass, Object arg)@b@ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException@b@ {@b@ Object[] args = { arg };@b@ return invokeConstructor(klass, args);@b@ }@b@@b@ public static Object invokeConstructor(Class klass, Object[] args)@b@ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException@b@ {@b@ if (null == args)@b@ args = EMPTY_OBJECT_ARRAY;@b@@b@ int arguments = args.length;@b@ Class[] parameterTypes = new Class[arguments];@b@ for (int i = 0; i < arguments; ++i)@b@ parameterTypes[i] = args[i].getClass();@b@@b@ return invokeConstructor(klass, args, parameterTypes);@b@ }@b@@b@ public static Object invokeConstructor(Class klass, Object[] args, Class[] parameterTypes)@b@ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException@b@ {@b@ if (parameterTypes == null)@b@ parameterTypes = EMPTY_CLASS_PARAMETERS;@b@@b@ if (args == null) {@b@ args = EMPTY_OBJECT_ARRAY;@b@ }@b@@b@ Constructor ctor = getMatchingAccessibleConstructor(klass, parameterTypes);@b@@b@ if (null == ctor) {@b@ throw new NoSuchMethodException("No such accessible constructor on object: " + klass.getName());@b@ }@b@@b@ return ctor.newInstance(args);@b@ }@b@@b@ public static Object invokeExactConstructor(Class klass, Object arg)@b@ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException@b@ {@b@ Object[] args = { arg };@b@ return invokeExactConstructor(klass, args);@b@ }@b@@b@ public static Object invokeExactConstructor(Class klass, Object[] args)@b@ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException@b@ {@b@ if (null == args)@b@ args = EMPTY_OBJECT_ARRAY;@b@@b@ int arguments = args.length;@b@ Class[] parameterTypes = new Class[arguments];@b@ for (int i = 0; i < arguments; ++i)@b@ parameterTypes[i] = args[i].getClass();@b@@b@ return invokeExactConstructor(klass, args, parameterTypes);@b@ }@b@@b@ public static Object invokeExactConstructor(Class klass, Object[] args, Class[] parameterTypes)@b@ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException@b@ {@b@ if (args == null) {@b@ args = EMPTY_OBJECT_ARRAY;@b@ }@b@@b@ if (parameterTypes == null) {@b@ parameterTypes = EMPTY_CLASS_PARAMETERS;@b@ }@b@@b@ Constructor ctor = getAccessibleConstructor(klass, parameterTypes);@b@ if (null == ctor) {@b@ throw new NoSuchMethodException("No such accessible constructor on object: " + klass.getName());@b@ }@b@@b@ return ctor.newInstance(args);@b@ }@b@@b@ public static Constructor getAccessibleConstructor(Class klass, Class parameterType)@b@ {@b@ Class[] parameterTypes = { parameterType };@b@ return getAccessibleConstructor(klass, parameterTypes);@b@ }@b@@b@ public static Constructor getAccessibleConstructor(Class klass, Class[] parameterTypes)@b@ {@b@ try@b@ {@b@ return getAccessibleConstructor(klass.getConstructor(parameterTypes));@b@ } catch (NoSuchMethodException e) {@b@ }@b@ return null;@b@ }@b@@b@ public static Constructor getAccessibleConstructor(Constructor ctor)@b@ {@b@ if (ctor == null) {@b@ return null;@b@ }@b@@b@ if (!(Modifier.isPublic(ctor.getModifiers()))) {@b@ return null;@b@ }@b@@b@ Class clazz = ctor.getDeclaringClass();@b@ if (Modifier.isPublic(clazz.getModifiers())) {@b@ return ctor;@b@ }@b@@b@ return null;@b@ }@b@@b@ private static Constructor getMatchingAccessibleConstructor(Class clazz, Class[] parameterTypes)@b@ {@b@ Constructor ctor;@b@ try@b@ {@b@ ctor = clazz.getConstructor(parameterTypes);@b@ try@b@ {@b@ ctor.setAccessible(true);@b@ }@b@ catch (SecurityException se) {@b@ }@b@ return ctor;@b@ }@b@ catch (NoSuchMethodException paramSize)@b@ {@b@ int paramSize = parameterTypes.length;@b@ Constructor[] ctors = clazz.getConstructors();@b@ int i = 0; int size = ctors.length; if (i >= size)@b@ break label139;@b@ Class[] ctorParams = ctors[i].getParameterTypes();@b@ int ctorParamSize = ctorParams.length;@b@ if (ctorParamSize == paramSize) {@b@ boolean match = true;@b@ for (int n = 0; n < ctorParamSize; ++n)@b@ if (!(MethodUtils.isAssignmentCompatible(ctorParams[n], parameterTypes[n])))@b@ {@b@ match = false;@b@ break;@b@ }@b@@b@@b@ if (match)@b@ {@b@ Constructor ctor = getAccessibleConstructor(ctors[i]);@b@ if (ctor != null) {@b@ try {@b@ ctor.setAccessible(true);@b@ }@b@ catch (SecurityException se)@b@ {@b@ }@b@@b@ return ctor;@b@ }@b@ }@b@ }@b@ ++i;@b@ }@b@@b@ label139: return null;@b@ }@b@}