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

Как работает @Target (ElementType.ANNOTATION_TYPE)

Аннотации Java помечены аннотацией @Target для объявления возможных точек соединения, которые могут быть украшены этой аннотацией. Значения TYPE, FIELD, METHOD и т.д. Перечисления ElementType понятны и понятны.

Вопрос

ПОЧЕМУ использовать значение @Target(ANNOTATION_TYPE)? Для чего нужны аннотированные аннотации? Каков их вклад? Дайте мне объяснение идеи, как это работает, и почему я должен использовать его. Некоторый уже существующий и хорошо известный пример его использования также будет отличным.

4b9b3361

Ответ 1

Вы можете использовать аннотированную аннотацию для создания мета-аннотации, например, рассмотрите это использование @Transactional в Spring:

/**
 * Shortcut and more descriptive "alias" for {@code @Transactional(propagation = Propagation.MANDATORY)}.
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(propagation = Propagation.MANDATORY)
public @interface RequiresExistingTransaction {
}

Когда вы включаете Spring для обработки аннотации @Transactional, он будет искать классы и методы, которые несут @Transactional или любую мета-аннотацию (аннотация, аннотированная с помощью @Transactional).

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

Ответ 2

Каждая аннотация, аннотированная @Target(ElementType.ANNOTATION_TYPE), называется Meta-annotation. Это означает, что вы можете определить свои собственные пользовательские аннотации, которые объединяют множество аннотаций, объединенных в одну аннотацию для создания composed annotations.

Хорошим примером из мира Android является StringDef

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

@Retention(SOURCE)
@StringDef({POWER_SERVICE, WINDOW_SERVICE, LAYOUT_INFLATER_SERVICE}) 
public @interface ServicesName {}

public static final String POWER_SERVICE = "power";
public static final String WINDOW_SERVICE = "window";
public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";

Инспектор кода будет обрабатывать @ServicesName и @WeekDays так же, как и @StringDef. В результате мы можем создать столько с именем StringDef, сколько нам нужно, и переопределить набор констант. @Target(ElementType.ANNOTATION_TYPE) это инструмент, который позволяет расширить использование аннотаций.

Ответ 3

Например, если аннотация выглядит как

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeAnnotation {

    String description() default "This is example for class annotation";
}

компилятор будет жаловаться в этой ситуации

@SomeAnnotation
public class SomeClass {

    @SomeAnnotation    // here it complaning
    public void someMethod(){}
}

Если вы измените

@Target(ElementType.TYPE) 

to

@Target({ElementType.METHOD, ElementType.TYPE}) 

он больше не будет жаловаться.

Ответ 4

Аннотации - это в основном дополнительные метаданные (информация), которые идут вместе с вашим кодом. Он может быть помещен вдоль боковых типов (классы, интерфейсы), методы и аргументы.

Это часто полезно во время компиляции и времени выполнения. Многие популярные API-интерфейсы, такие как Java EE 5+, Spring, аннотирование AspectJ для ясности и согласованности кода.

Использование аннотации часто позволяет коду быть более читабельным, более понятным.

Я бы рекомендовал вам прочитать главу аннотации в учебнике Java

В прошлом метаданные часто указываются как xml файл, и для кого-то, кто пытается понять код, сложно найти другой файл конфигурации xml. последний API сервлета Java позволяет отображать сервлет просто с помощью аннотации - в отличие от отображения web.xml:

@WebServlet("/response")
public class ResponseServlet extends HttpServlet {
  // servlet code here...
}