
mockit.internal.util.ConstructorReflection Maven / Gradle / Ivy
/*
* Copyright (c) 2006-2012 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.util;
import java.lang.reflect.*;
import static mockit.internal.util.ParameterReflection.*;
public final class ConstructorReflection
{
public static T newInstance(Class aClass, Class>[] parameterTypes, Object... initArgs)
{
Constructor constructor = findSpecifiedConstructor(aClass, parameterTypes);
return invoke(constructor, initArgs);
}
private static Constructor findSpecifiedConstructor(Class> theClass, Class>[] paramTypes)
{
for (Constructor> declaredConstructor : theClass.getDeclaredConstructors()) {
Class>[] declaredParameterTypes = declaredConstructor.getParameterTypes();
int firstRealParameter = indexOfFirstRealParameter(declaredParameterTypes, paramTypes);
if (
firstRealParameter >= 0 &&
matchesParameterTypes(declaredParameterTypes, paramTypes, firstRealParameter)
) {
//noinspection unchecked
return (Constructor) declaredConstructor;
}
}
String paramTypesDesc = getParameterTypesDescription(paramTypes);
throw new IllegalArgumentException(
"Specified constructor not found: " + theClass.getSimpleName() + paramTypesDesc);
}
public static T invoke(Constructor constructor, Object... initArgs)
{
Utilities.ensureThatMemberIsAccessible(constructor);
Object[] args = initArgs != null? initArgs : getDefaultParameterValues(constructor);
try {
return constructor.newInstance(args);
}
catch (InstantiationException e) {
throw new RuntimeException(e);
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof Error) {
throw (Error) cause;
}
else if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
else {
ThrowOfCheckedException.doThrow((Exception) cause);
return null;
}
}
}
private static Object[] getDefaultParameterValues(Constructor> constructor)
{
Class>[] parameterTypes = constructor.getParameterTypes();
int numParameters = parameterTypes.length;
Object[] defaultArgs = new Object[numParameters];
for (int i = 0; i < numParameters; i++) {
Class> paramType = parameterTypes[i];
defaultArgs[i] = DefaultValues.computeForType(paramType);
}
return defaultArgs;
}
public static T newInstance(String className, Class>[] parameterTypes, Object... initArgs)
{
Class theClass = ClassLoad.loadClass(className);
return newInstance(theClass, parameterTypes, initArgs);
}
public static T newInstance(String className, Object... nonNullArgs)
{
Class>[] argTypes = getArgumentTypesFromArgumentValues(nonNullArgs);
Class theClass = ClassLoad.loadClass(className);
Constructor constructor = findCompatibleConstructor(theClass, argTypes);
return invoke(constructor, nonNullArgs);
}
private static Constructor findCompatibleConstructor(Class> theClass, Class>[] argTypes)
{
Constructor found = null;
Class>[] foundParameters = null;
Constructor>[] declaredConstructors = theClass.getDeclaredConstructors();
for (Constructor> declaredConstructor : declaredConstructors) {
Class>[] declaredParamTypes = declaredConstructor.getParameterTypes();
int firstRealParameter = indexOfFirstRealParameter(declaredParamTypes, argTypes);
if (
firstRealParameter >= 0 &&
(matchesParameterTypes(declaredParamTypes, argTypes, firstRealParameter) ||
acceptsArgumentTypes(declaredParamTypes, argTypes, firstRealParameter)) &&
(found == null || hasMoreSpecificTypes(declaredParamTypes, foundParameters))
) {
//noinspection unchecked
found = (Constructor) declaredConstructor;
foundParameters = declaredParamTypes;
}
}
if (found != null) {
return found;
}
Class> declaringClass = theClass.getDeclaringClass();
Class>[] paramTypes = declaredConstructors[0].getParameterTypes();
if (paramTypes[0] == declaringClass && paramTypes.length > argTypes.length) {
throw new IllegalArgumentException("Invalid instantiation of inner class; use newInnerInstance instead");
}
String argTypesDesc = getParameterTypesDescription(argTypes);
throw new IllegalArgumentException("No compatible constructor found: " + theClass.getSimpleName() + argTypesDesc);
}
public static T newInstance(Class extends T> aClass, Object... nonNullArgs)
{
Class>[] argTypes = getArgumentTypesFromArgumentValues(nonNullArgs);
Constructor constructor = findCompatibleConstructor(aClass, argTypes);
return invoke(constructor, nonNullArgs);
}
public static T newInstance(Class aClass)
{
return newInstance(aClass, NO_PARAMETERS);
}
public static T newInstanceUsingDefaultConstructor(Class aClass)
{
try {
//noinspection ClassNewInstance
return aClass.newInstance();
}
catch (InstantiationException ie) {
throw new RuntimeException(ie);
}
catch (IllegalAccessException ignore) {
return newInstance(aClass);
}
}
public static T newInnerInstance(Class extends T> innerClass, Object outerInstance, Object... nonNullArgs)
{
Object[] initArgs = argumentsWithExtraFirstValue(nonNullArgs, outerInstance);
return newInstance(innerClass, initArgs);
}
public static T newInnerInstance(String innerClassName, Object outerInstance, Object... nonNullArgs)
{
String className = outerInstance.getClass().getName() + '$' + innerClassName;
Class innerClass = ClassLoad.loadClass(className);
return newInnerInstance(innerClass, outerInstance, nonNullArgs);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy