我正在尝试找到一种在运行时检索方法的“父”的简单方法。 (可能使用反射)通过方法的“父”,我指的是在继承树中首先定义所述方法的类。理想情况下,这也适用于Generics。
示例:
import json
import time
while True:
with open('/tmp/install-report.json') as json_data:
d = json.load(json_data)
for key, value in d.iteritems():
print key, value
time.sleep(1)
如果我想获得Class3#doSomething的'父母',它应该检索Class1和Class2。 Java中是否存在任何此类方法,甚至可能?
答案 0 :(得分:0)
参考此question
它在接口上循环:for (Class<?> c : cls.getInterfaces())
...
您还可以使用for (Class<?> c : cls.getClasses())
答案 1 :(得分: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();
}
}