panda.lang.reflect.Constructors Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of panda-core Show documentation
Show all versions of panda-core Show documentation
Panda Core is the core module of Panda Framework, it contains commonly used utility classes similar to apache-commons.
package panda.lang.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import panda.lang.Classes;
import panda.lang.Strings;
/**
* Miscellaneous {@link Constructor} related utility functions.
*
*/
@SuppressWarnings("unchecked")
public class Constructors {
public static Constructor getConstructor(Class type, Object... args) {
Class>[] ats = Classes.toClass(args);
return getConstructor(type, ats);
}
/**
* Returns a {@link Constructor} for the given method signature, or null if no such
* Constructor can be found.
*
* @param type the (non-null) type of {@link Object} the returned {@link Constructor}
* should create
* @param argTypes a non-null array of types describing the parameters to the
* {@link Constructor}.
* @return a {@link Constructor} for the given method signature, or null if no such
* Constructor can be found.
* @see #invokeConstructor
*/
@SuppressWarnings("rawtypes")
public static Constructor getConstructor(Class type, Class>... argTypes) {
if (null == type || null == argTypes) {
throw new NullPointerException();
}
Constructor ctor = null;
try {
ctor = type.getConstructor(argTypes);
}
catch (Exception e) {
ctor = null;
}
if (null == ctor) {
// no directly declared matching constructor,
// look for something that will work
// this should really be more careful to
// adhere to the jls mechanism for late binding
Constructor[] ctors = type.getConstructors();
for (int i = 0; i < ctors.length; i++) {
Class[] paramtypes = ctors[i].getParameterTypes();
if (paramtypes.length == argTypes.length) {
boolean canuse = true;
for (int j = 0; j < paramtypes.length; j++) {
if (argTypes[j] == null || paramtypes[j].isAssignableFrom(argTypes[j])) {
continue;
}
else {
canuse = false;
break;
}
}
if (canuse == true) {
ctor = ctors[i];
break;
}
}
}
}
return ctor;
}
/**
* Returns a {@link Constructor} for the given method signature, or null if no such
* Constructor can be found.
*
* @param type the (non-null) type of {@link Object} the returned {@link Constructor}
* should create
* @param argLength argument count.
* @return a {@link Constructor} for the given method signature, or null if no such
* Constructor can be found.
* @see #invokeConstructor
*/
@SuppressWarnings("rawtypes")
public static Constructor getConstructor(Class type, int argLength) {
if (null == type) {
throw new NullPointerException();
}
if (argLength < 0) {
throw new IllegalArgumentException();
}
Constructor[] ctors = type.getConstructors();
for (int i = 0; i < ctors.length; i++) {
Class[] paramtypes = ctors[i].getParameterTypes();
if (paramtypes.length == argLength) {
return ctors[i];
}
}
return null;
}
/**
* Creates a new instance of the specified type using a {@link Constructor}
* described by the given parameter types and values.
*
* @param type the type of {@link Object} to be created
* @param argTypes a non-null array of types describing the parameters to the
* {@link Constructor}.
* @param argValues a non-null array containing the values of the parameters to the
* {@link Constructor}.
* @return a new instance of the specified type using a {@link Constructor}
* described by the given parameter types and values.
* @exception InstantiationException if an error occurs
* @exception IllegalAccessException if an error occurs
* @exception InvocationTargetException if an error occurs
* @exception NoSuchMethodException if an Constructor does not exists
*/
public static T invokeConstructor(Class type, Class>[] argTypes, Object[] argValues)
throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Constructor c = Constructors.getConstructor(type, argTypes);
if (c == null) {
throw new NoSuchMethodException("Failed to find constructor for " + type + '(' + Strings.join(argTypes, ", ") + ')');
}
return c.newInstance(argValues);
}
}