Я хочу найти конкретную аннотацию каждого метода в классе и если метод с этой аннотацией найден, я бы хотел вызвать его. Кроме того, если он не найден в текущем классе, должна быть сделана проверка всех классов наследования.
Моя проблема в том, что могут быть некоторые защищенные методы, частные и т.д., И я хотел бы игнорировать эти модификаторы и получить доступ ко всем методам (т.е. Даже если это частный и т.д.),
Так вот как я вызываю (дано имя аннотации, которую я ищу:
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
является рекурсивным вызовом.
Вам нужно использовать 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 и similars.
Вы должны сделать доступный метод до вызова
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
(как обычный вызов)Моя проблема в том, что могут быть некоторые защищенные методы, частные и т.д., И я хотел бы игнорировать эти модификаторы и получить доступ ко всем методам (т.е. Даже если это частный и т.д.),
Вам необходимо вызвать Method.setAccessible(true)
прежде чем вызывать его, не забывая впоследствии восстановить его исходное значение, в блоке finally.
getDeclaredMethods
?