Подтвердить что ты не робот

Как я могу ссылаться на реализации метода в обработке аннотаций?

Я играю с обработкой аннотации Java (javax).

Предположим, что у меня есть аннотация для методов:

@Target(ElementType.METHOD)
public @interface MethodAnnotation { }

Теперь я хочу обработать все методы, которые переопределены с типом с помощью аннотированного метода:

interface MyInterface() {
    @MethodAnnotation
    void f()
}

class MyClass implements MyInterface {
    override void f() { } // <- I want to process this method
}

@Inherited мета-аннотация, кажется, не подходит здесь:

Обратите внимание, что этот тип мета-аннотации не действует, если аннотированный тип используется для комментирования чего-либо другого, кроме класса.

Кроме того, возможно ли обработать метод унаследованного класса, который не переопределяется в подклассе? Вот так:

class MyClass {
    @MethodAnnotation
    void f() { }
}

class MySubClass extends MyClass { } // <- I want to process its f()
                                     //    or at least to find out that it doesn't
                                     //    override the method

Как я могу получить доступ к переопределенным методам определенного метода в AbstractProcessor?

Я думаю, для этого мне нужно найти подклассы класса eclosing, но я тоже не нашел способ сделать это.

UPD. Я полагаю, что это возможно, используя RoundEnvironment.getRootElements(), но не нашел подходящего способа сделать это.

4b9b3361

Ответ 1

Короткий ответ заключается в том, что готовая обработка аннотаций не облегчит вам задачу, но это можно сделать.

Вместо того, чтобы использовать обычный механизм отправки для обработки, вам действительно придется обрабатывать каждый метод и выполнять фильтрацию самостоятельно.

Шаг 1:

Определите свой процессор так, чтобы он поддерживал все аннотации, используя "*" в качестве поддерживаемого типа аннотации. Это будет означать, что ваш процессор будет вызываться каждый раунд.

Шаг 2:

Используйте getRootElements, чтобы получить весь набор элементов каждый раунд.

Шаг 3:

Создайте ElementScanner8, чтобы пересечь любой элемент, который вы найдете, для поиска ExecutableElement s. Если вы хотите верить, что переопределенные методы аннотируются с помощью @Override, вы можете сделать быстрый фильтр для них. В противном случае просто посмотрите на них.

Шаг 4:

Теперь вам нужно проверить, отменяет ли метод метод с помощью аннотации, которую вы ищете. Нет простого способа получить методы, которые данный метод переопределил, поэтому вам нужно получить охватывающий элемент метода, посмотреть его superclass и реализованные интерфейсы (рекурсивно), получите их закрытые элементы, отфильтровать методы, а проверить, был ли он переопределен по рассматриваемому методу. Если это так, вы можете проверить аннотации, чтобы узнать, есть ли у вас какой-то интерес.

Шаг 5:

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

Ответ 2

в соответствии с javadoc javax.annotation.processing.Processor в Jsr269-1.8

Аннотация присутствует, если она соответствует определению присутствия данный в AnnotatedConstruct. Короче говоря, аннотация рассматривается присутствовать в целях обнаружения, если оно прямо присутствует или присутствующих через наследование. Аннотации не считаются присутствующими из-за того, что он обернут аннотацией контейнера...

JavaDoc AnnotatedConstruct # getAnnotationsByType говорит, что он возвращает косвенно существующие аннотации, поэтому я думаю, что вы должны отсканировать методы и проверить, косвенно ли они аннотация с использованием этого вызова. Что-то в духе this.

Отказ от ответственности... не пробовал это;)

Ответ 3

Аннотации методов не наследуются. Аннотации типа могут быть наследованы с помощью аннотации "@Inherited".

Что вы можете сделать, так это определить функциональный интерфейс с унаследованной аннотацией типа, однако я не знаю, достаточно ли это для вас.

Ответ 4

Если эти аннотации доступны во время выполнения и вы хотите связаться с ними во время выполнения, вы можете использовать библиотеку Reflections.

Например:

Collection<URL> urls = ClasspathHelper.forPackage("nl.shopname.location.domain");

Reflections reflections = new Reflections(
    new ConfigurationBuilder().setUrls(urls).setScanners(new FieldAnnotationsScanner()));

Set<Field> fieldsWithAnnotation = reflections.getFieldsAnnotatedWith(MyAnnotation.class);