public static Method getMatchingMethod()

in src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java [723:770]


    public static Method getMatchingMethod(final Class<?> cls, final String methodName,
            final Class<?>... parameterTypes) {
        Objects.requireNonNull(cls, "cls");
        Validate.notEmpty(methodName, "methodName");

        final List<Method> methods = Stream.of(cls.getDeclaredMethods())
                .filter(method -> method.getName().equals(methodName))
                .collect(Collectors.toList());

        ClassUtils.getAllSuperclasses(cls).stream()
                .map(Class::getDeclaredMethods)
                .flatMap(Stream::of)
                .filter(method -> method.getName().equals(methodName))
                .forEach(methods::add);

        for (final Method method : methods) {
            if (Arrays.deepEquals(method.getParameterTypes(), parameterTypes)) {
                return method;
            }
        }

        final TreeMap<Integer, List<Method>> candidates = new TreeMap<>();

        methods.stream()
                .filter(method -> ClassUtils.isAssignable(parameterTypes, method.getParameterTypes(), true))
                .forEach(method -> {
                    final int distance = distance(parameterTypes, method.getParameterTypes());
                    final List<Method> candidatesAtDistance = candidates.computeIfAbsent(distance, k -> new ArrayList<>());
                    candidatesAtDistance.add(method);
                });

        if (candidates.isEmpty()) {
            return null;
        }

        final List<Method> bestCandidates = candidates.values().iterator().next();
        if (bestCandidates.size() == 1 || !Objects.equals(bestCandidates.get(0).getDeclaringClass(),
                bestCandidates.get(1).getDeclaringClass())) {
            return bestCandidates.get(0);
        }

        throw new IllegalStateException(
                String.format("Found multiple candidates for method %s on class %s : %s",
                        methodName + Stream.of(parameterTypes).map(String::valueOf).collect(Collectors.joining(",", "(", ")")),
                        cls.getName(),
                        bestCandidates.stream().map(Method::toString).collect(Collectors.joining(",", "[", "]")))
        );
    }