1
2
3
4
5
6 package mockit.internal.reflection;
7
8 import static mockit.internal.reflection.ParameterReflection.getParameterTypesDescription;
9 import static mockit.internal.reflection.ParameterReflection.indexOfFirstRealParameter;
10 import static mockit.internal.reflection.ParameterReflection.matchesParameterTypes;
11 import static mockit.internal.util.Utilities.ensureThatMemberIsAccessible;
12
13 import edu.umd.cs.findbugs.annotations.NonNull;
14 import edu.umd.cs.findbugs.annotations.Nullable;
15
16 import java.lang.reflect.Constructor;
17 import java.lang.reflect.InvocationTargetException;
18
19 import org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator;
20
21 public final class ConstructorReflection {
22 private ConstructorReflection() {
23 }
24
25 @NonNull
26 static <T> Constructor<T> findSpecifiedConstructor(@NonNull Class<?> theClass, @NonNull Class<?>[] paramTypes) {
27 for (Constructor<?> declaredConstructor : theClass.getDeclaredConstructors()) {
28 Class<?>[] declaredParameterTypes = declaredConstructor.getParameterTypes();
29 int firstRealParameter = indexOfFirstRealParameter(declaredParameterTypes, paramTypes);
30
31 if (firstRealParameter >= 0
32 && matchesParameterTypes(declaredParameterTypes, paramTypes, firstRealParameter)) {
33
34 return (Constructor<T>) declaredConstructor;
35 }
36 }
37
38 String paramTypesDesc = getParameterTypesDescription(paramTypes);
39
40 throw new IllegalArgumentException(
41 "Specified constructor not found: " + theClass.getSimpleName() + paramTypesDesc);
42 }
43
44 @NonNull
45 public static <T> T invokeAccessible(@NonNull Constructor<T> constructor, @NonNull Object... initArgs) {
46 if (!constructor.isAccessible()) {
47 constructor.setAccessible(true);
48 }
49 try {
50 return constructor.newInstance(initArgs);
51 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
52 Throwable cause = e instanceof InvocationTargetException ? e.getCause() : e;
53
54 if (cause instanceof Error) {
55 throw (Error) cause;
56 }
57 if (cause instanceof RuntimeException) {
58 throw (RuntimeException) cause;
59 }
60 ThrowOfCheckedException.doThrow((Exception) cause);
61 throw new IllegalStateException("Should never get here", cause);
62 }
63 }
64
65 public static void newInstanceUsingCompatibleConstructor(@NonNull Class<?> aClass, @NonNull String argument)
66 throws ReflectiveOperationException {
67 Constructor<?> constructor = aClass.getDeclaredConstructor(String.class);
68 ensureThatMemberIsAccessible(constructor);
69 constructor.newInstance(argument);
70 }
71
72 @NonNull
73 public static <T> T newInstanceUsingDefaultConstructor(@NonNull Class<T> aClass) {
74 try {
75 Constructor<T> constructor = aClass.getDeclaredConstructor();
76 ensureThatMemberIsAccessible(constructor);
77 return constructor.newInstance();
78 } catch (NoSuchMethodException | InstantiationException | IllegalAccessException e) {
79 throw new RuntimeException(e);
80 } catch (InvocationTargetException e) {
81 throw new RuntimeException(e.getTargetException());
82 }
83 }
84
85 @Nullable
86 public static <T> T newInstanceUsingDefaultConstructorIfAvailable(@NonNull Class<T> aClass) {
87 try {
88 Constructor<T> constructor = aClass.getDeclaredConstructor();
89 return constructor.newInstance();
90 } catch (NoSuchMethodException | InstantiationException | IllegalAccessException
91 | InvocationTargetException ignore) {
92 return null;
93 }
94 }
95
96 @Nullable
97 public static <T> T newInstanceUsingPublicConstructorIfAvailable(@NonNull Class<T> aClass,
98 @NonNull Class<?>[] parameterTypes, @NonNull Object... initArgs) {
99 Constructor<T> publicConstructor;
100 try {
101 publicConstructor = aClass.getConstructor(parameterTypes);
102 } catch (NoSuchMethodException ignore) {
103 return null;
104 }
105
106 return invokeAccessible(publicConstructor, initArgs);
107 }
108
109 @NonNull
110 public static <T> T newInstanceUsingPublicDefaultConstructor(@NonNull Class<T> aClass) {
111 Constructor<T> publicConstructor;
112 try {
113 publicConstructor = aClass.getConstructor();
114 } catch (NoSuchMethodException e) {
115 throw new RuntimeException(e);
116 }
117
118 return invokeAccessible(publicConstructor);
119 }
120
121 @NonNull
122 public static <T> T newUninitializedInstance(@NonNull Class<T> aClass) {
123 SunReflectionFactoryInstantiator<T> ref = new SunReflectionFactoryInstantiator<>(aClass);
124 return ref.newInstance();
125 }
126 }