code: public static Method getMatchingMethod(final Class<?> cls, final String methodName,
              final Class<?>... parameterTypes) {
          Validate.notNull(cls, "Null class not allowed.");
          Validate.notEmpty(methodName, "Null or blank methodName not allowed.");
  
          // Address methods in superclasses
          Method[] methodArray = cls.getDeclaredMethods();
          final List<Class<?>> superclassList = ClassUtils.getAllSuperclasses(cls);
          for (final Class<?> klass : superclassList) {
              methodArray = ArrayUtils.addAll(methodArray, klass.getDeclaredMethods());
          }
  
          Method inexactMatch = null;
          for (final Method method : methodArray) {
              if (methodName.equals(method.getName()) &&
                      Objects.deepEquals(parameterTypes, method.getParameterTypes())) {
                  return method;
              } else if (methodName.equals(method.getName()) &&
                      ClassUtils.isAssignable(parameterTypes, method.getParameterTypes(), true)) {
                  if (inexactMatch == null) {
                      inexactMatch = method;
                  } else if (distance(parameterTypes, method.getParameterTypes())
                          < distance(parameterTypes, inexactMatch.getParameterTypes())) {
                      inexactMatch = method;
                  }
              }
  
          }
          return inexactMatch;
      }
docs: <p>Retrieves a method whether or not it's accessible. If no such method
  can be found, return {@code null}.</p>
  @param cls The class that will be subjected to the method search
  @param methodName The method that we wish to call
  @param parameterTypes Argument class types
  @return The method
  
  @since 3.5