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
- newInstance(Class clazz)
- newInstance(Class clazz, Class>[] argumentTypes, Object[] arguments)
- newInstance(Class clazz, Class>[] parameterTypes, Object[] initargs)
- newInstance(Class cls)
- newInstance(Class cls)
- newInstance(Class clz, Class argType, K arg)
- newInstance(Class componentType, int size)
- newInstance(Class elementType, int len)
- newInstance(Class klass)