Как известно, в Java есть три варианта аннотаций по RetentionPolicy:

  • Compile — видны только компилятору, полезны для преобразования кода.
  • Runtime — видны и при исполнении, можно сделать что-то рефлексией, например, создать класс из JSON.
  • Class — записаны в байткоде, но не видны через рефлексию, могут из пользоваться инструментацией или в плагинах (чтобы делать что-то при их загрузке).

А теперь минутка извращений! Несмотря на то, что через рефлексию не видны аннотации с уровнем Class, если очень-очень надо, то можно… перепрочитать класс через что-то вроде

clazz.getResourceAsStream(clazz.simpleName + ".class")

и запихать это в ClassReader из ASM с переопределенным visitAnnotation. К счастью, в прод этот код не попал, но пики надо держать острыми.