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