Description
Retrieve the constructor of a class for given optional argument types.
License
Apache License
Parameter
Parameter | Description |
---|
cls | class to retrieve the constructor from |
argsTypes | argument types |
T | type to retrieve the constructor from |
Exception
Parameter | Description |
---|
NoSuchMethodException | if a matching method is not found. |
Return
matching constructor for given optional argument values
Declaration
public static <T> Constructor<T> getConstructorOptional(Class<T> cls, Class<?>... argsTypes)
throws NoSuchMethodException
Method Source Code
//package com.java2s;
//License from project: Apache License
import java.lang.reflect.Constructor;
import java.util.Arrays;
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. jav a 2s . c o m*/
* Retrieve the constructor of a class for given optional 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 optional argument values
* @throws NoSuchMethodException if a matching method is not found.
*/
public static <T> Constructor<T> getConstructorOptional(Class<T> cls, Class<?>... argsTypes)
throws NoSuchMethodException {
return getConstructorOptional(0, cls, argsTypes);
}
/**
* Retrieve the constructor of a class for given optional argument types, considering mandatory values at the
* beginning of the given types.
*
* @param mandatoryCount number of mandatory arguments at the beginning of the given arguments
* @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 optional argument values
* @throws NoSuchMethodException if a matching method is not found.
*/
public static <T> Constructor<T> getConstructorOptional(int mandatoryCount, Class<T> cls, Class<?>... argsTypes)
throws NoSuchMethodException {
while (true) {
try {
return getConstructor(cls, argsTypes);
} catch (NoSuchMethodException e) {
if (argsTypes.length == mandatoryCount) {
break;
}
argsTypes = Arrays.copyOf(argsTypes, argsTypes.length - 1);
}
}
throw new NoSuchMethodException("Can't find any valid constructor.");
}
/**
* 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
- getConstructorDescriptor(final Constructor> c)
- getConstructorForArguments( java.lang.reflect.Constructor[] constructors, Object... arguments)
- getConstructorFromSignature(Class> clazz, String cstrSig)
- getConstructorIfAvailable(Class clazz, Class>... paramTypes)
- getConstructorLabel(java.lang.reflect.Constructor> con)
- getConstructorOrFail(Class clazz, Class>... argTypes)
- getConstructors(Class cl)
- getConstructors(Class infoClass)
- getConstructors(Class> clazz)