Easy way to find the parents method at runtime?

I am trying to find an easy way to get the "parents" of a method at runtime. (Perhaps using reflection). By the "parents" of the method, I mean the classes that defined the specified method first in the inheritance tree. This ideally will also work with Generics.

Example:

public interface Class1<O> {
    void doSomething(O s);
}

public interface Class2 {
    void doSomething(String s);
}

public class Class3 implements Class1<String>, Class2 {
    public void doSomething(String s) {
        // Something
    }
}

Here he should get Class1 and Class2 if I want to get the "parents" of class 3 doSomething. Is there any such method in Java or is this possible?

+4
source share
2 answers

Referring to this question. It was a loop on the interfaces: for (Class<?> c : cls.getInterfaces())... You can also loop through classes usingfor (Class<?> c : cls.getClasses())

0

, , ( , , ), . , , , ( , , ). , Object. , , , .

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestParent {

    public static void main(String[] args) {
        // prints Class1 and Class2
        System.out.println(getParents(Class3.class, "doSomething"));

        // prints Class5
        System.out.println(getParents(Class3.class, "run"));
    }

    private static List<Class> getParents(Class<?> type, String methodName) {
        Method method = getMethodByName(type, methodName);
        if (method == null)
            return Collections.emptyList();

        Class nextClass = type.getSuperclass();
        Class parent = null;

        while (!nextClass.equals(Object.class)) {

            if (hasMethod(nextClass, methodName, method)) {
                parent = nextClass;
            }

            nextClass = nextClass.getSuperclass();
        }

        List<Class> parents = new ArrayList<>();

        if (parent != null) {
            // search parent interfaces
            for (Class t : parent.getInterfaces()) {
                if (hasMethod(t, methodName, method)) {
                    parents.add(t);
                }
            }

            if (parents.isEmpty())
                parents.add(parent);

        } else {
            // search our interfaces
            for (Class t : type.getInterfaces()) {
                if (hasMethod(t, methodName, method)) {
                    parents.add(t);
                }
            }
        }

        return parents;
    }

    private static boolean equalMethod(Method m1, Method m2) {
        return m1.getName().equals(m2.getName()) && m1.getReturnType().equals(m2.getReturnType());
        // uncomment if parameter types must be the same
        //&& Arrays.equals(m1.getParameterTypes(), m2.getParameterTypes());
    }

    private static boolean hasMethod(Class<?> type, String methodName, Method method) {
        Method m = getMethodByName(type, methodName);

        return m != null && equalMethod(method, m);
    }

    private static Method getMethodByName(Class<?> type, String methodName) {
        for (Method m : type.getDeclaredMethods()) {
            if (m.getName().equals(methodName)) {
                return m;
            }
        }

        return null;
    }

    public interface Class1<O> {
        void doSomething(O s);
    }

    public interface Class2 {
        void doSomething(String s);
    }

    public class Class3 extends Class4 implements Class1<String>, Class2 {
        public void doSomething(String s) {
            // Something
        }

        @Override
        void run() {

        }
    }

    public abstract class Class4 extends Class5 {
        abstract void run();
    }

    public abstract class Class5 {
        abstract void run();
    }
}
0

Source: https://habr.com/ru/post/1651927/


All Articles