33import java .lang .reflect .Field ;
44import java .lang .reflect .Method ;
55
6+ import io .vavr .control .Try ;
7+ import org .jetbrains .annotations .ApiStatus ;
68import org .jetbrains .annotations .NotNull ;
79import org .jetbrains .annotations .Nullable ;
810
@@ -15,15 +17,14 @@ public final class ReflectHelper {
1517 * Try to get the {@link Class} based on its classpath.
1618 *
1719 * @param classPath The target classpath.
18- * @return A {@link Class} if found, else null.
20+ * @return A {@link Try} containing the {@link Class} if found, else a failure.
21+ *
22+ * @since 5.7
1923 */
20- @ Nullable
21- public static Class <?> getClass (String classPath ) {
22- try {
23- return Class .forName (classPath );
24- } catch (ClassNotFoundException e ) {
25- return null ;
26- }
24+ @ ApiStatus .AvailableSince ("5.7" )
25+ @ NotNull
26+ public static Try <Class <?>> tryGetClass (@ NotNull String classPath ) {
27+ return Try .of (() -> Class .forName (classPath ));
2728 }
2829
2930 /**
@@ -33,7 +34,168 @@ public static Class<?> getClass(String classPath) {
3334 * @return True if class path is a valid class, else false.
3435 */
3536 public static boolean hasClass (String classPath ) {
36- return getClass (classPath ) != null ;
37+ return tryGetClass (classPath ).isSuccess ();
38+ }
39+
40+ /**
41+ * Try to get a {@link Method} from a given class.
42+ *
43+ * @param clazz The class to search the method on.
44+ * @param methodName Name of the method to get.
45+ * @param parameterTypes Parameters present for that method.
46+ * @param <C> The class type.
47+ * @return A {@link Try} containing the {@link Method} if found, else a failure.
48+ *
49+ * @since 5.7
50+ */
51+ @ ApiStatus .AvailableSince ("5.7" )
52+ @ NotNull
53+ public static <C > Try <Method > tryGetMethod (@ NotNull Class <C > clazz , @ NotNull String methodName , Class <?>... parameterTypes ) {
54+ return Try .of (() -> clazz .getMethod (methodName , parameterTypes ))
55+ .orElse (Try .of (() -> {
56+ Method method = clazz .getDeclaredMethod (methodName , parameterTypes );
57+ method .setAccessible (true );
58+ return method ;
59+ }));
60+ }
61+
62+ /**
63+ * Check if a {@link Method} exists on a given class.
64+ *
65+ * @param clazz The class to search the method on.
66+ * @param methodName Name of the method to check.
67+ * @param parameterTypes Parameters present for that method.
68+ * @return True if method exists, else false.
69+ *
70+ * @since 5.7
71+ */
72+ @ ApiStatus .AvailableSince ("5.7" )
73+ public static boolean hasMethod (@ NotNull Class <?> clazz , @ NotNull String methodName , Class <?>... parameterTypes ) {
74+ return tryGetMethod (clazz , methodName , parameterTypes ).isSuccess ();
75+ }
76+
77+ /**
78+ * Try to invoke a {@link Method} on a class instance.
79+ *
80+ * @param classInstance Instance of the class responsible for the method.
81+ * @param method The method to invoke.
82+ * @param parameters Parameters needed when invoking the method.
83+ * @param <C> The class type.
84+ * @param <R> The return type of the method.
85+ * @return A {@link Try} containing the return value of the method if found, else a failure.
86+ *
87+ * @since 5.7
88+ */
89+ @ ApiStatus .AvailableSince ("5.7" )
90+ @ NotNull
91+ @ SuppressWarnings ("unchecked" )
92+ public static <C , R > Try <R > tryInvokeMethod (@ NotNull C classInstance , @ NotNull Method method , Object ...parameters ) {
93+ return Try .of (() -> (R ) method .invoke (classInstance , parameters ));
94+ }
95+
96+ /**
97+ * Try to invoke a static {@link Method}.
98+ *
99+ * @param method The static method to invoke.
100+ * @param parameters Parameters needed when invoking the method.
101+ * @param <R> The return type of the method.
102+ * @return A {@link Try} containing the return value of the method if found, else a failure.
103+ *
104+ * @since 5.7
105+ */
106+ @ ApiStatus .AvailableSince ("5.7" )
107+ @ NotNull
108+ @ SuppressWarnings ("unchecked" )
109+ public static <R > Try <R > tryInvokeStaticMethod (@ NotNull Method method , Object ...parameters ) {
110+ return Try .of (() -> (R ) method .invoke (null , parameters ));
111+ }
112+
113+ /**
114+ * Try to get a {@link Field} from a given class.
115+ *
116+ * @param clazz The class to search the field on.
117+ * @param fieldName Name of the field to get.
118+ * @param <C> The class type.
119+ * @return A {@link Try} containing the {@link Field} if found, else a failure.
120+ *
121+ * @since 5.7
122+ */
123+ @ ApiStatus .AvailableSince ("5.7" )
124+ @ NotNull
125+ public static <C > Try <Field > tryGetField (@ NotNull Class <C > clazz , @ NotNull String fieldName ) {
126+ return Try .of (() -> clazz .getField (fieldName ))
127+ .orElse (Try .of (() -> {
128+ Field field = clazz .getDeclaredField (fieldName );
129+ field .setAccessible (true );
130+ return field ;
131+ }));
132+ }
133+
134+ /**
135+ * Check if a {@link Field} exists on a given class.
136+ *
137+ * @param clazz The class to search the field on.
138+ * @param fieldName Name of the field to check.
139+ * @return True if field exists, else false.
140+ *
141+ * @since 5.7
142+ */
143+ @ ApiStatus .AvailableSince ("5.7" )
144+ public static boolean hasField (@ NotNull Class <?> clazz , @ NotNull String fieldName ) {
145+ return tryGetField (clazz , fieldName ).isSuccess ();
146+ }
147+
148+ /**
149+ * Try to get the value of a {@link Field} from an instance of the class responsible.
150+ *
151+ * @param classInstance Instance of the class to get the field value from.
152+ * @param field The field to get the value from.
153+ * @param fieldType Type of the field.
154+ * @param <C> The class type.
155+ * @param <V> The field value type.
156+ * @return A {@link Try} containing the field value if found, else a failure.
157+ *
158+ * @since 5.7
159+ */
160+ @ ApiStatus .AvailableSince ("5.7" )
161+ @ NotNull
162+ public static <C , V > Try <V > tryGetFieldValue (@ NotNull C classInstance , @ NotNull Field field , @ NotNull Class <V > fieldType ) {
163+ return Try .of (() -> fieldType .cast (field .get (classInstance )));
164+ }
165+
166+ /**
167+ * Try to get the value of a static {@link Field}.
168+ *
169+ * @param field The static field to get the value from.
170+ * @param fieldType Type of the field.
171+ * @param <V> The field value type.
172+ * @return A {@link Try} containing the field value if found, else a failure.
173+ *
174+ * @since 5.7
175+ */
176+ @ ApiStatus .AvailableSince ("5.7" )
177+ @ NotNull
178+ public static <V > Try <V > tryGetStaticFieldValue (@ NotNull Field field , @ NotNull Class <V > fieldType ) {
179+ return Try .of (() -> fieldType .cast (field .get (null )));
180+ }
181+
182+ /**
183+ * Try to get the {@link Class} based on its classpath.
184+ *
185+ * @param classPath The target classpath.
186+ * @return A {@link Class} if found, else null.
187+ *
188+ * @deprecated Use {@link #tryGetClass(String)} instead, which returns a {@link Try} that can be used to handle
189+ * the failure case more explicitly.
190+ */
191+ @ Deprecated (forRemoval = true , since = "5.7" )
192+ @ Nullable
193+ public static Class <?> getClass (String classPath ) {
194+ try {
195+ return Class .forName (classPath );
196+ } catch (ClassNotFoundException e ) {
197+ return null ;
198+ }
37199 }
38200
39201 /**
@@ -44,7 +206,11 @@ public static boolean hasClass(String classPath) {
44206 * @param parameterTypes Parameters present for that method.
45207 * @param <C> The class type.
46208 * @return A {@link Method} if found, else null.
209+ *
210+ * @deprecated Use {@link #tryGetMethod(Class, String, Class[])} instead, which returns a {@link Try} that can be
211+ * used to handle the failure case more explicitly.
47212 */
213+ @ Deprecated (forRemoval = true , since = "5.7" )
48214 @ Nullable
49215 public static <C > Method getMethod (Class <C > clazz , String methodName , Class <?>... parameterTypes ) {
50216 try {
@@ -64,7 +230,11 @@ public static <C> Method getMethod(Class<C> clazz, String methodName, Class<?>..
64230 * @param parameterTypes Parameters present for that method.
65231 * @param <C> The class type.
66232 * @return A {@link Method} if found, else null.
233+ *
234+ * @deprecated Use {@link #tryGetMethod(Class, String, Class[])} instead, which returns a {@link Try} that can be
235+ * used to handle the failure case more explicitly.
67236 */
237+ @ Deprecated (forRemoval = true , since = "5.7" )
68238 @ Nullable
69239 public static <C > Method getMethod (C classInstance , String methodName , Class <?>... parameterTypes ) {
70240 return getMethod (classInstance .getClass (), methodName , parameterTypes );
@@ -79,8 +249,13 @@ public static <C> Method getMethod(C classInstance, String methodName, Class<?>.
79249 * @param <C> The class type.
80250 * @param <R> The return type.
81251 * @return Return value of the method call if any, else null.
252+ *
253+ * @deprecated Use {@link #tryInvokeMethod(Object, Method, Object...)} instead, which returns a {@link Try} that can
254+ * be used to handle the failure case more explicitly.
82255 */
256+ @ Deprecated (forRemoval = true , since = "5.7" )
83257 @ Nullable
258+ @ SuppressWarnings ("unchecked" )
84259 public static <C , R > R invokeMethod (C classInstance , Method method , Object ...parameters ) {
85260 try {
86261 return (R ) method .invoke (classInstance , parameters );
@@ -96,7 +271,11 @@ public static <C, R> R invokeMethod(C classInstance, Method method, Object...par
96271 * @param fieldName Name of the field to get.
97272 * @param <C> The class type.
98273 * @return A {@link Field} if found, else null.
274+ *
275+ * @deprecated Use {@link #tryGetField(Class, String)} instead, which returns a {@link Try} that can be used to
276+ * handle the failure case more explicitly.
99277 */
278+ @ Deprecated (forRemoval = true , since = "5.7" )
100279 @ Nullable
101280 public static <C > Field getField (Class <C > clazz , String fieldName ) {
102281 try {
@@ -115,7 +294,11 @@ public static <C> Field getField(Class<C> clazz, String fieldName) {
115294 * @param fieldName Name of the field to get.
116295 * @param <C> The class type.
117296 * @return A {@link Field} if found, else null.
297+ *
298+ * @deprecated Use {@link #tryGetField(Class, String)} instead, which returns a {@link Try} that can be used to
299+ * handle the failure case more explicitly.
118300 */
301+ @ Deprecated (forRemoval = true , since = "5.7" )
119302 @ Nullable
120303 public static <C > Field getField (C classInstance , String fieldName ) {
121304 return getField (classInstance .getClass (), fieldName );
@@ -130,7 +313,11 @@ public static <C> Field getField(C classInstance, String fieldName) {
130313 * @param <C> The class type.
131314 * @param <V> The field value type.
132315 * @return The field value if any, else null.
316+ *
317+ * @deprecated Use {@link #tryGetFieldValue(Object, Field, Class)} instead, which returns a {@link Try} that can be
318+ * used to handle the failure case more explicitly.
133319 */
320+ @ Deprecated (forRemoval = true , since = "5.7" )
134321 @ Nullable
135322 public static <C , V > V getFieldValue (C classInstance , @ Nullable Field field , @ NotNull Class <V > fieldType ) {
136323 try {
@@ -153,7 +340,11 @@ public static <C, V> V getFieldValue(C classInstance, @Nullable Field field, @No
153340 * @param <C> The class type.
154341 * @param <V> The field value type.
155342 * @return The field value if any, else null.
343+ *
344+ * @deprecated Use {@link #tryGetField(Class, String)} then map to {@link #tryGetFieldValue(Object, Field, Class)} instead,
345+ * which returns a {@link Try} that can be used to handle the failure case more explicitly.
156346 */
347+ @ Deprecated (forRemoval = true , since = "5.7" )
157348 @ Nullable
158349 public static <C , V > V getFieldValue (C classInstance , @ Nullable String fieldName , @ NotNull Class <V > fieldType ) {
159350 return getFieldValue (classInstance , getField (classInstance , fieldName ), fieldType );
0 commit comments