Как я могу получить значение аннотации по аннотированному методу?Получить атрибут аннотации Java
у меня есть:
@myAnnotation(attribute1 = value1, attibute2 = value2)
public void myMethod()
{
//I want to get value1 here
}
Как я могу получить значение аннотации по аннотированному методу?Получить атрибут аннотации Java
у меня есть:
@myAnnotation(attribute1 = value1, attibute2 = value2)
public void myMethod()
{
//I want to get value1 here
}
Method
экземпляр.Что-то вроде:
Method m = getClass().getMethod("myMethod");
MyAnnotation a = m.getAnnotation(MyAnnotation.class);
MyValueType value1 = a.attribute1();
Вам нужно поймать/обрабатывать соответствующие исключения, конечно. Выше предполагает, что вы на самом деле извлечение метод из текущего класса (заменить getClass()
с Class.forName()
иначе) и рассматриваемым методом является публичным (использование getDeclaredMethods()
, если это не так)
Две важных вещи:
RUNTIME
, поэтому вы можете получить доступ к аннотации во время выполнения. По умолчанию используется время компиляции, что означает, что аннотации доступны в файле класса, но не могут быть доступны во время выполнения с использованием отражения.Полный пример:
@Retention(RetentionPolicy.RUNTIME)
public static @interface MyAnnotation {
String value1();
int value2();
}
@Test
@MyAnnotation(value1 = "Foo", value2 = 1337)
public void testAnnotation() throws Exception {
Method[] methods = getClass().getMethods();
Method method = methods[0];
assertEquals("testAnnotation", method.getName());
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
assertEquals("Foo", annotation.value1());
assertEquals(1337, annotation.value2());
}
Существует способ получения текущего метода: либо Thread.currentThread(). getStackTrace() [2] .getMethodName() 'или' new Throwable(). FillInStackTrace(). GetStackTrace() [0].getMethodName() 'должен это делать. – ChssPly76
+1 для упоминания Сохранение – basszero
@ ChssPly76, построение stacktrace не является полностью надежным, поскольку в javadocs упоминается: «Некоторые виртуальные машины могут при некоторых обстоятельствах опустить один или несколько кадров стека из трассировки стека. В крайнем случае, виртуальной машине, которая не имеет информации о трассировке стека [...], разрешено возвращать массив нулевой длины из этого метода ». – gustafc
@mhaller: немного слишком долго для комментария на ваш пост. Очевидно, что потребуется дальнейшее уточнение для борьбы с перегруженными методами, но это не невозможно .:
import java.lang.reflect.Method;
public class Hack {
public static void main (String[] args) {
(new Hack()).foobar();
}
public void foobar() {
Method here = getCurrentMethod(this);
System.out.format("And here we are: %s\n", here);
}
public static final Method getCurrentMethod(Object o) {
String s = Thread.currentThread().getStackTrace()[2].getMethodName();
Method cm = null;
for(Method m : o.getClass().getMethods()){
if(m.getName().equals(s)){
cm = m; break;
}
}
return cm;
}
}
[редактировать: кредит/спасибо Александр Приймак для пятнистость ошибки в главном()]
У меня такое ощущение, что если вы на самом деле делаете это в производственном коде, он призывает Великих Старейшин, чтобы поглотить вашу душу! –
@Skip Head - почему? Здесь есть две вещи: (1) индекс массива ** в теории ** может отличаться от 2 на некоторых JVM, но это легко обойти, пройдя весь след; (2) это не будет работать для перегруженных методов; вы можете сделать черную магию с javassist, чтобы угадать правильный, основанный на номере строки, но это действительно немного. Другое дело, что, тем не менее, он отлично работает - как вы думаете, работают трассировки стека? – ChssPly76
@ ChssPly76: Не нужно ходить по всему следу. Метод трассировки начинается сверху и проходит до тех пор, пока не найдет себя. А вызывающий - следующий. – alphazero
Чтобы получить текущий метод, попробуйте использовать этот код:
Thread.currentThread().getStackTrace()[1].getClassName().toString()+\".\"+Thread.currentThread().getStackTrace()[1].getMethodName().toString()
Можете ли вы предоставить более подробную информацию о том, что вы пытаетесь выполнить? – Carl
Как я уже сказал, я хочу использовать значение атрибута1, не повторяя его код –
Это не эффективный метод программирования. Здесь нет преимущества наличия значений, заданных в аннотации, в отличие от того, чтобы они были установлены в конечных переменных внутри кода или были установлены в конечных статических переменных вне метода. – Jherico