Как работает @Target (ElementType.ANNOTATION_TYPE)
Аннотации Java помечены аннотацией @Target
для объявления возможных точек соединения, которые могут быть украшены этой аннотацией. Значения TYPE
, FIELD
, METHOD
и т.д. Перечисления ElementType
понятны и понятны.
Вопрос
ПОЧЕМУ использовать значение @Target(ANNOTATION_TYPE)
? Для чего нужны аннотированные аннотации? Каков их вклад? Дайте мне объяснение идеи, как это работает, и почему я должен использовать его. Некоторый уже существующий и хорошо известный пример его использования также будет отличным.
Ответы
Ответ 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...
}