diff --git a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java index 4d1af9d2175d..f1e655fcd316 100644 --- a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,7 @@ * @author Costin Leau * @author Sam Brannen * @author Chris Beams + * @author Yong-Hyun Kim * @since 1.2.2 */ public abstract class ReflectionUtils { @@ -463,6 +464,7 @@ private static Method[] getDeclaredMethods(Class clazz, boolean defensive) { if (result == null) { try { Method[] declaredMethods = clazz.getDeclaredMethods(); + Arrays.sort(declaredMethods, ReflectionUtils::methodDeclaringClassHierarchySorter); List defaultMethods = findDefaultMethodsOnInterfaces(clazz); if (defaultMethods != null) { result = new Method[declaredMethods.length + defaultMethods.size()]; @@ -486,6 +488,18 @@ private static Method[] getDeclaredMethods(Class clazz, boolean defensive) { return (result.length == 0 || !defensive) ? result : result.clone(); } + private static int methodDeclaringClassHierarchySorter(Method method1, Method method2) { + Class clazz1 = method1.getDeclaringClass(); + Class clazz2 = method2.getDeclaringClass(); + if (clazz1 == clazz2) { + return 0; + } + if (clazz1.isAssignableFrom(clazz2)) { + return 1; + } + return -1; + } + @Nullable private static List findDefaultMethodsOnInterfaces(Class clazz) { List result = null; diff --git a/spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java index c962f096d0a0..efdc5e9b8a85 100644 --- a/spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ * @author Juergen Hoeller * @author Sam Brannen * @author Arjen Poutsma + * @author Yong-Hyun Kim */ class ReflectionUtilsTests { @@ -231,6 +232,8 @@ void findMethod() { assertThat(ReflectionUtils.findMethod(B.class, "bar", String.class)).isNotNull(); assertThat(ReflectionUtils.findMethod(B.class, "foo", Integer.class)).isNotNull(); assertThat(ReflectionUtils.findMethod(B.class, "getClass")).isNotNull(); + assertThat(ReflectionUtils.findMethod(B.class, "baz", String[].class).isBridge()).isFalse(); + assertThat(ReflectionUtils.findMethod(B.class, "baz", String[].class).isVarArgs()).isTrue(); } @Test @@ -381,6 +384,10 @@ private static class A { @SuppressWarnings({ "unused", "RedundantThrows" }) private void foo(Integer i) throws RemoteException { } + + protected Object baz(String... args) { + return "A"; + } } @SuppressWarnings("unused") @@ -396,6 +403,11 @@ int add(int... args) { } return sum; } + + @Override + protected String baz(String... args) { + return "B"; + } } }