我想查找类中每个方法的特定注释,如果找到带有该注释的方法,我想调用它。 此外,如果在当前类中找不到它,则应检查所有继承类。
我的问题是可能有一些受保护的方法,私有等等。我想忽略这些修饰符并获得对所有方法的访问权(即使它是私有的等等)
所以这就是我调用的方式(给出的是我正在寻找的注释的名称:
if (m.isAnnotationPresent(Given.class)) {
m.invoke(instObj, intArgument);
}
(这就是我检查类层次结构的其余部分 - 如果我在某个地方犯了错误,请赐教我:
Class<?> superC = c.getSuperclass();
while (!(superC.equals(Object.class))) {
handleGiven(instObj, superC, methods, currentSentence,
methodArgument);
当handleGiven
是递归调用时。
答案 0 :(得分:2)
您需要使用getDeclaredMethods来获取所有方法(公共,受保护等),如下所示:
public Method findMethodWithAnnotation(Class<?> clazz,
Class<? extends Annotation> annotation) {
for (Method m : clazz.getDeclaredMethods()) {
if (m.isAnnotationPresent(annotation)) {
return m;
}
}
return null;
}
并按照以下方式检查:
Class<?> clazz = ..; //get the class
Method m = null;
do {
m = findMethodWithAnnotation(clazz, DesiredAnnotation.class);
clazz = clazz.getSuperclass();
} while (m == null && clazz != null);
System.out.println(m);
还要确保您的注释具有以下注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
如果您需要字段注释,请查看getDeclaredFields和类似方法。
您需要在调用之前使方法可访问
m.setAccessible(true);
如果您想要更紧凑和递归的实现,可以更改为:
public Method findMethodWithAnnotation(Class<?> clazz,
Class<? extends Annotation> annotation) {
if (clazz == Object.class || clazz == null) return null;
for (Method m : clazz.getDeclaredMethods()) {
if (m.isAnnotationPresent(annotation)) {
return m;
}
}
return findMethodWithAnnotation(clazz.getSuperClass(), annotation);
}
使用方法是:
Method m = findMethodWithAnnotation(clazz, DesiredAnnotation.class)
if (m == null) log("Nor the class, or any superclass have the desired annotation")
else {
m.setAccessitble(true);
m.invoke(obj, arguments);
}
A
有一个覆盖方法desiredMethod
,没有注释,并且扩展了一个类SuperA
,则会有一个方法desiredMethod
,带有所需的注释,返回SuperA#desiredMethod
,但是当你调用它时,它将在A
类中调用(就像正常的调用一样)答案 1 :(得分:0)
我的问题是可能有一些方法受到保护,私有等等。我想忽略这些修饰符并获得对所有方法的访问权(即使它是私有等)。
你需要在调用它之前调用Method.setAccessible(true)
,而不是忘记在finally块中恢复其原始值。