imToken v2.14.1版本的 MD5 值为:83050b2c91219b46832c8336279e7878
以下内容为反编译后的 ConstructorInstantiator.java 源代码,内容仅作参考
package org.mockito.internal.creation.instance;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.mockito.creation.instance.InstantiationException;
import org.mockito.creation.instance.Instantiator;
import org.mockito.internal.configuration.plugins.Plugins;
import org.mockito.internal.util.Primitives;
import org.mockito.internal.util.StringUtil;
public class ConstructorInstantiator implements Instantiator {
private final Object[] constructorArgs;
private final boolean hasOuterClassInstance;
public ConstructorInstantiator(boolean z2, Object... objArr) {
this.hasOuterClassInstance = z2;
this.constructorArgs = objArr;
}
@Override
public <T> T newInstance(Class<T> cls) {
return (T) withParams(cls, this.constructorArgs);
}
private <T> T withParams(Class<T> cls, Object... objArr) {
Constructor<?>[] declaredConstructors;
LinkedList linkedList = new LinkedList();
try {
for (Constructor<?> constructor : cls.getDeclaredConstructors()) {
if (paramsMatch(constructor.getParameterTypes(), objArr)) {
evaluateConstructor(linkedList, constructor);
}
}
if (linkedList.size() == 1) {
return (T) invokeConstructor(linkedList.get(0), objArr);
}
if (linkedList.isEmpty()) {
throw noMatchingConstructor(cls);
}
throw multipleMatchingConstructors(cls, linkedList);
} catch (Exception e2) {
throw paramsException(cls, e2);
}
}
private static <T> T invokeConstructor(Constructor<?> constructor, Object... objArr) throws InstantiationException, IllegalAccessException, InvocationTargetException {
return (T) Plugins.getMemberAccessor().newInstance(constructor, objArr);
}
private InstantiationException paramsException(Class<?> cls, Exception exc) {
return new InstantiationException(StringUtil.join("Unable to create instance of '" + cls.getSimpleName() + "'.", "Please ensure the target class has " + constructorArgsString() + " and executes cleanly."), exc);
}
private String constructorArgTypes() {
boolean z2 = this.hasOuterClassInstance;
String[] strArr = new String[this.constructorArgs.length - (z2 ? 1 : 0)];
int i2 = z2 ? 1 : 0;
while (true) {
Object[] objArr = this.constructorArgs;
if (i2 < objArr.length) {
strArr[i2 - (z2 ? 1 : 0)] = objArr[i2] == null ? null : objArr[i2].getClass().getName();
i2++;
} else {
return Arrays.toString(strArr);
}
}
}
private InstantiationException noMatchingConstructor(Class<?> cls) {
String constructorArgsString = constructorArgsString();
String str = this.hasOuterClassInstance ? " and provided outer instance is correct" : "";
return new InstantiationException(StringUtil.join("Unable to create instance of '" + cls.getSimpleName() + "'.", "Please ensure that the target class has " + constructorArgsString + str + "."), null);
}
private String constructorArgsString() {
Object[] objArr = this.constructorArgs;
if (objArr.length == 0 || (this.hasOuterClassInstance && objArr.length == 1)) {
return "a 0-arg constructor";
}
return "a constructor that matches these argument types: " + constructorArgTypes();
}
private InstantiationException multipleMatchingConstructors(Class<?> cls, List<Constructor<?>> list) {
return new InstantiationException(StringUtil.join("Unable to create instance of '" + cls.getSimpleName() + "'.", "Multiple constructors could be matched to arguments of types " + constructorArgTypes() + ":", StringUtil.join("", " - ", list), "If you believe that Mockito could do a better job deciding on which constructor to use, please let us know.", "Ticket 685 contains the discussion and a workaround for ambiguous constructors using inner class.", "See https://github.com/mockito/mockito/issues/685"), null);
}
private static boolean paramsMatch(Class<?>[] clsArr, Object[] objArr) {
if (objArr.length != clsArr.length) {
return false;
}
for (int i2 = 0; i2 < objArr.length; i2++) {
if (objArr[i2] == null) {
if (clsArr[i2].isPrimitive()) {
return false;
}
} else if ((!clsArr[i2].isPrimitive() && !clsArr[i2].isInstance(objArr[i2])) || (clsArr[i2].isPrimitive() && !clsArr[i2].equals(Primitives.primitiveTypeOf(objArr[i2].getClass())))) {
return false;
}
}
return true;
}
private void evaluateConstructor(List<Constructor<?>> list, Constructor<?> constructor) {
Class<?>[] parameterTypes = constructor.getParameterTypes();
boolean z2 = false;
boolean z3 = false;
for (int i2 = 0; i2 < parameterTypes.length; i2++) {
Class<?> cls = parameterTypes[i2];
if (!cls.isPrimitive()) {
for (Constructor<?> constructor2 : list) {
Class<?> cls2 = constructor2.getParameterTypes()[i2];
if (cls != cls2) {
if (cls.isAssignableFrom(cls2)) {
z2 = true;
} else {
z3 = true;
}
}
}
}
}
if (!z2) {
list.clear();
}
if (z3 || !z2) {
list.add(constructor);
}
}
}