Аннотации Java возвращают имена загадочных классов

Я немного новичок в Java, поэтому, возможно, я неправильно понимаю случаи использования аннотаций в java. Моя проблема заключается в следующем:

После аннотации метода я получаю имена классов, такие как $Proxy31 при проверке аннотаций метода. Мне любопытно, почему я получаю имена классов для моих аннотаций, которые похожи на это, и что я могу сделать, чтобы исправить эту проблему.

Method m = this.remoteServiceClass.getMethod(rpcRequest.getMethod().getName());
RequiredPermission a = m.getAnnotation(RequiredPermission.class);

Это возвращает нулевую аннотацию, хотя я знаю, что метод, который он ищет, имеет аннотацию RequiredPermission.

for(Annotation a : m.getAnnotations())
{
    System.out.println(a.getClass().getName());
}

Это печатает имена классов $Proxy31.

Ответы

Ответ 1

Учитывая аннотацию a, вам нужно вызвать annotationType(), а не getClass(), чтобы определить тип аннотации. Объект Annotation - это просто прокси-сервер, представляющий этот экземпляр аннотации этого класса.

Object o = ...;
Class c = o.getClass();
Annotation[] as = c.getAnnotations();
for (Annotation a : as) {
   // prints out the proxy class name
   System.out.println(a.getClass().getName());
   // prints out the name of the actual annotation
   System.out.println(a.annotationType().getName());
}

Ответ 2

Когда вы добавляете аннотации в исходный код, Java на самом деле создает кучу интерфейсов и классов "под капотом", чтобы позволить вам (или вашим инструментам) запрашивать у программы информацию об аннотациях с использованием ограничений. Аннотации метода создают "dyanmic proxies", и, соответственно, Java создает для вас классы, возможно, с именем Proxy.

Если вы заинтересованы в этом, прочитайте на java.lang.reflect.InvocationHandler и его подтип, AnnotationInvocationHandler

При этом вам не нужно беспокоиться о том, что на самом деле генерирует Java. Я подозреваю, что вы неправильно используете отражение, чтобы проверить свои аннотации из программы Java.

Ответ 3

также.. не забудьте установить это:

@Retention(RetentionPolicy.RUNTIME)

в вашей аннотации, чтобы он оставался вне компиляции.