public static Set<Method> getOverrideHierarchy(final Method method, final Interfaces interfacesBehavior) {
        Validate.notNull(method);
        final Set<Method> result = new LinkedHashSet<>();
        result.add(method);

        final Class<?>[] parameterTypes = method.getParameterTypes();

        final Class<?> declaringClass = method.getDeclaringClass();

        final Iterator<Class<?>> hierarchy = ClassUtils.hierarchy(declaringClass, interfacesBehavior).iterator();
        //skip the declaring class :P
        hierarchy.next();
        hierarchyTraversal: while (hierarchy.hasNext()) {
            final Class<?> c = hierarchy.next();
            final Method m = getMatchingAccessibleMethod(c, method.getName(), parameterTypes);
            if (m == null) {
                continue;
            }
            if (Arrays.equals(m.getParameterTypes(), parameterTypes)) {
                // matches without generics
                result.add(m);
                continue;
            }
            // necessary to get arguments every time in the case that we are including interfaces
            final Map<TypeVariable<?>, Type> typeArguments = TypeUtils.getTypeArguments(declaringClass, m.getDeclaringClass());
            for (int i = 0; i < parameterTypes.length; i++) {
                final Type childType = TypeUtils.unrollVariables(typeArguments, method.getGenericParameterTypes()[i]);
                final Type parentType = TypeUtils.unrollVariables(typeArguments, m.getGenericParameterTypes()[i]);
                if (!TypeUtils.equals(childType, parentType)) {
                    continue hierarchyTraversal;
                }
            }
            result.add(m);
        }
        return result;
    }
public static Set < Method > getOverrideHierarchy ( final Method method , final Interfaces interfacesBehavior ) { Validate . notNull ( method ) ; final Set < Method > result = new LinkedHashSet < > ( ) ; result . add ( method ) ; final Class < ? > [ ] parameterTypes = method . getParameterTypes ( ) ; final Class < ? > declaringClass = method . getDeclaringClass ( ) ; final Iterator < Class < ? > > hierarchy = ClassUtils . hierarchy ( declaringClass , interfacesBehavior ) . iterator ( ) ; hierarchy . next ( ) ; hierarchyTraversal : while ( hierarchy . hasNext ( ) ) { final Class < ? > c = hierarchy . next ( ) ; final Method m = getMatchingAccessibleMethod ( c , method . getName ( ) , parameterTypes ) ; if ( m == null ) { continue ; } if ( Arrays . equals ( m . getParameterTypes ( ) , parameterTypes ) ) { result . add ( m ) ; continue ; } final Map < TypeVariable < ? > , Type > typeArguments = TypeUtils . getTypeArguments ( declaringClass , m . getDeclaringClass ( ) ) ; for ( int i = 0 ; i < parameterTypes . length ; i ++ ) { final Type childType = TypeUtils . unrollVariables ( typeArguments , method . getGenericParameterTypes ( ) [ i ] ) ; final Type parentType = TypeUtils . unrollVariables ( typeArguments , m . getGenericParameterTypes ( ) [ i ] ) ; if ( ! TypeUtils . equals ( childType , parentType ) ) { continue hierarchyTraversal ; } } result . add ( m ) ; } return result ; }
Get the hierarchy of overridden methods down to {@code result} respecting generics.
@param method lowest to consider
@param interfacesBehavior whether to search interfaces, {@code null} {@code implies} false
@return Set&lt;Method&gt; in ascending order from sub- to superclass
@throws NullPointerException if the specified method is {@code null}
@since 3.2