diff --git a/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java index d894f91fb8..82ab35bf4e 100644 --- a/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java @@ -391,6 +391,32 @@ class ClassUtilsTests { assertThat(ClassUtils.determineCommonAncestor(String.class, List.class)).isNull(); } + @Test + void getMostSpecificMethod() throws NoSuchMethodException { + Method defaultPrintMethod = ClassUtils.getMethod(MethodsInterface.class, "defaultPrint"); + assertThat(ClassUtils.getMostSpecificMethod(defaultPrintMethod, MethodsInterfaceImplementation.class)).isEqualTo(defaultPrintMethod); + assertThat(ClassUtils.getMostSpecificMethod(defaultPrintMethod, SubMethodsInterfaceImplementation.class)).isEqualTo(defaultPrintMethod); + + Method printMethod = ClassUtils.getMethod(MethodsInterface.class, "print", String.class); + assertThat(ClassUtils.getMostSpecificMethod(printMethod, MethodsInterfaceImplementation.class)).isNotEqualTo(printMethod); + assertThat(ClassUtils.getMostSpecificMethod(printMethod, MethodsInterfaceImplementation.class)) + .isEqualTo(ClassUtils.getMethod(MethodsInterfaceImplementation.class, "print", String.class)); + assertThat(ClassUtils.getMostSpecificMethod(printMethod, SubMethodsInterfaceImplementation.class)) + .isEqualTo(ClassUtils.getMethod(MethodsInterfaceImplementation.class, "print", String.class)); + + Method protectedPrintMethod = MethodsInterfaceImplementation.class.getDeclaredMethod("protectedPrint"); + assertThat(ClassUtils.getMostSpecificMethod(protectedPrintMethod, MethodsInterfaceImplementation.class)).isEqualTo(protectedPrintMethod); + assertThat(ClassUtils.getMostSpecificMethod(protectedPrintMethod, SubMethodsInterfaceImplementation.class)) + .isEqualTo(SubMethodsInterfaceImplementation.class.getDeclaredMethod("protectedPrint")); + + + Method packageAccessiblePrintMethod = MethodsInterfaceImplementation.class.getDeclaredMethod("packageAccessiblePrint"); + assertThat(ClassUtils.getMostSpecificMethod(packageAccessiblePrintMethod, MethodsInterfaceImplementation.class)) + .isEqualTo(packageAccessiblePrintMethod); + assertThat(ClassUtils.getMostSpecificMethod(packageAccessiblePrintMethod, SubMethodsInterfaceImplementation.class)) + .isEqualTo(ClassUtils.getMethod(SubMethodsInterfaceImplementation.class, "packageAccessiblePrint")); + } + @ParameterizedTest @WrapperTypes void isPrimitiveWrapper(Class type) { @@ -558,4 +584,44 @@ class ClassUtilsTests { } } + @SuppressWarnings("unused") + private interface MethodsInterface{ + + default void defaultPrint(){ + + } + void print(String messages); + } + + @SuppressWarnings("unused") + private class MethodsInterfaceImplementation implements MethodsInterface{ + + @Override + public void print(String message) { + + } + + protected void protectedPrint(){ + + } + + void packageAccessiblePrint(){ + + } + } + + @SuppressWarnings("unused") + private class SubMethodsInterfaceImplementation extends MethodsInterfaceImplementation{ + + @Override + protected void protectedPrint(){ + + } + + public void packageAccessiblePrint(){ + + } + + } + }