@@ -1483,10 +1483,8 @@ private static Method findInterfaceMethodIfPossible(String methodName, Class<?>[
1483
1483
}
1484
1484
1485
1485
/**
1486
- * Get the first publicly accessible method in the supplied method's type hierarchy that
1486
+ * Get the highest publicly accessible method in the supplied method's type hierarchy that
1487
1487
* has a method signature equivalent to the supplied method, if possible.
1488
- * <p>If the supplied method is {@code public} and declared in a {@code public} type,
1489
- * the supplied method will be returned.
1490
1488
* <p>Otherwise, this method recursively searches the class hierarchy and implemented
1491
1489
* interfaces for an equivalent method that is {@code public} and declared in a
1492
1490
* {@code public} type.
@@ -1509,19 +1507,23 @@ private static Method findInterfaceMethodIfPossible(String methodName, Class<?>[
1509
1507
* @see #getMostSpecificMethod(Method, Class)
1510
1508
*/
1511
1509
public static Method getPubliclyAccessibleMethodIfPossible (Method method , @ Nullable Class <?> targetClass ) {
1512
- Class <?> declaringClass = method .getDeclaringClass ();
1513
- // If the method is not public, we can abort the search immediately; or if the method's
1514
- // declaring class is public, the method is already publicly accessible.
1515
- if (!Modifier .isPublic (method .getModifiers ()) || Modifier .isPublic (declaringClass .getModifiers ())) {
1510
+ // If the method is not public, we can abort the search immediately.
1511
+ if (!Modifier .isPublic (method .getModifiers ())) {
1516
1512
return method ;
1517
1513
}
1518
1514
1519
1515
Method interfaceMethod = getInterfaceMethodIfPossible (method , targetClass , true );
1520
1516
// If we found a method in a public interface, return the interface method.
1521
- if (! interfaceMethod . equals ( method ) ) {
1517
+ if (interfaceMethod != method ) {
1522
1518
return interfaceMethod ;
1523
1519
}
1524
1520
1521
+ Class <?> declaringClass = method .getDeclaringClass ();
1522
+ // Bypass cache for java.lang.Object unless it is actually an overridable method declared there.
1523
+ if (declaringClass .getSuperclass () == Object .class && !ReflectionUtils .isObjectMethod (method )) {
1524
+ return method ;
1525
+ }
1526
+
1525
1527
Method result = publiclyAccessibleMethodCache .computeIfAbsent (method ,
1526
1528
key -> findPubliclyAccessibleMethodIfPossible (key .getName (), key .getParameterTypes (), declaringClass ));
1527
1529
return (result != null ? result : method );
@@ -1531,19 +1533,19 @@ public static Method getPubliclyAccessibleMethodIfPossible(Method method, @Nulla
1531
1533
private static Method findPubliclyAccessibleMethodIfPossible (
1532
1534
String methodName , Class <?>[] parameterTypes , Class <?> declaringClass ) {
1533
1535
1536
+ Method result = null ;
1534
1537
Class <?> current = declaringClass .getSuperclass ();
1535
1538
while (current != null ) {
1536
- if (Modifier .isPublic (current .getModifiers ())) {
1537
- try {
1538
- return current .getDeclaredMethod (methodName , parameterTypes );
1539
- }
1540
- catch (NoSuchMethodException ex ) {
1541
- // ignore
1542
- }
1539
+ Method method = getMethodOrNull (current , methodName , parameterTypes );
1540
+ if (method == null ) {
1541
+ break ;
1543
1542
}
1544
- current = current .getSuperclass ();
1543
+ if (Modifier .isPublic (method .getDeclaringClass ().getModifiers ())) {
1544
+ result = method ;
1545
+ }
1546
+ current = method .getDeclaringClass ().getSuperclass ();
1545
1547
}
1546
- return null ;
1548
+ return result ;
1547
1549
}
1548
1550
1549
1551
/**
0 commit comments