@@ -230,7 +230,9 @@ public static Method findMethod(Class<?> clazz, String name, @Nullable Class<?>.
230
230
Assert .notNull (name , "Method name must not be null" );
231
231
Class <?> searchType = clazz ;
232
232
while (searchType != null ) {
233
- Method [] methods = (searchType .isInterface () ? searchType .getMethods () : getDeclaredMethods (searchType ));
233
+ Method [] methods = searchType .isInterface () ?
234
+ searchType .getMethods () :
235
+ getDeclaredMethods (searchType , false );
234
236
for (Method method : methods ) {
235
237
if (name .equals (method .getName ()) &&
236
238
(paramTypes == null || Arrays .equals (paramTypes , method .getParameterTypes ()))) {
@@ -308,7 +310,7 @@ public static boolean declaresException(Method method, Class<?> exceptionType) {
308
310
* @see #doWithMethods
309
311
*/
310
312
public static void doWithLocalMethods (Class <?> clazz , MethodCallback mc ) {
311
- Method [] methods = getDeclaredMethods (clazz );
313
+ Method [] methods = getDeclaredMethods (clazz , false );
312
314
for (Method method : methods ) {
313
315
try {
314
316
mc .doWith (method );
@@ -345,7 +347,7 @@ public static void doWithMethods(Class<?> clazz, MethodCallback mc) {
345
347
*/
346
348
public static void doWithMethods (Class <?> clazz , MethodCallback mc , @ Nullable MethodFilter mf ) {
347
349
// Keep backing up the inheritance hierarchy.
348
- Method [] methods = getDeclaredMethods (clazz );
350
+ Method [] methods = getDeclaredMethods (clazz , false );
349
351
for (Method method : methods ) {
350
352
if (mf != null && !mf .matches (method )) {
351
353
continue ;
@@ -429,16 +431,22 @@ public static Method[] getUniqueDeclaredMethods(Class<?> leafClass, @Nullable Me
429
431
}
430
432
431
433
/**
432
- * This variant retrieves {@link Class#getDeclaredMethods()} from a local cache
433
- * in order to avoid the JVM's SecurityManager check and defensive array copying.
434
- * In addition, it also includes Java 8 default methods from locally implemented
435
- * interfaces, since those are effectively to be treated just like declared methods.
434
+ * Variant of {@link Class#getDeclaredMethods()} that uses a local cache in
435
+ * order to avoid the JVM's SecurityManager check and new Method instances.
436
+ * In addition, it also includes Java 8 default methods from locally
437
+ * implemented interfaces, since those are effectively to be treated just
438
+ * like declared methods.
436
439
* @param clazz the class to introspect
437
440
* @return the cached array of methods
438
441
* @throws IllegalStateException if introspection fails
442
+ * @since 5.2
439
443
* @see Class#getDeclaredMethods()
440
444
*/
441
- private static Method [] getDeclaredMethods (Class <?> clazz ) {
445
+ public static Method [] getDeclaredMethods (Class <?> clazz ) {
446
+ return getDeclaredMethods (clazz , true );
447
+ }
448
+
449
+ private static Method [] getDeclaredMethods (Class <?> clazz , boolean defensive ) {
442
450
Assert .notNull (clazz , "Class must not be null" );
443
451
Method [] result = declaredMethodsCache .get (clazz );
444
452
if (result == null ) {
@@ -464,7 +472,7 @@ private static Method[] getDeclaredMethods(Class<?> clazz) {
464
472
"] from ClassLoader [" + clazz .getClassLoader () + "]" , ex );
465
473
}
466
474
}
467
- return result ;
475
+ return ( result . length == 0 || ! defensive ) ? result : result . clone () ;
468
476
}
469
477
470
478
@ Nullable
0 commit comments