введение
давным-давно,XML
всегдаJava
Основные метаданные конфигурации фреймворка (meta data
) Главный путь. но какцентрализованныйИнструмент управления метаданными для , элемент конфигурации находится слишком далеко от кода действия"далекий», что очень вредно для обслуживания и отладки кода.XML
本身复杂的语法结构,往往令码农们大感头疼。一种与作用代码耦合在一起的元数据配置方式呼之欲出。 тогдааннотация(Аннотации) вJDK 5
Официально появляются в линии зрения разработчика.
ежедневное использованиеSpring Boot
Студенты, которые более знакомы с использованием аннотаций, должны быть знакомы с ним. Но задумывались ли вы когда-нибудь об этих аннотациях, таких как@Configuration @Component @Bean
И так далее, в чем его суть, и как он играет свою конкретную роль?
Характер аннотаций
Официальный сайт Oracle определяет аннотации как:
Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.
Аннотации — это форма метаданных, предоставляющая данные о программе, которые не принадлежат самой программе. Аннотация не оказывает прямого влияния на работу кода, который она аннотирует.
Из этого определения мы видим, что, во-первых, аннотация несет в себе метаданные, а во-вторых, может вызывать некоторые операции, связанные с метаданными, ноНе влияет на логику аннотированного кода.
пока вJDK
В интерфейсе Annotation есть строка комментариев, поэтому написано:
/**
* The common interface extended by all annotation types.
* ...
*/
public interface Annotation {...}
Это показывает, что другие аннотации расширеныAnnotation
Этот интерфейс, то есть сущность аннотации, и есть интерфейс.
Для Spring Boot в примечании в качестве примера:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
На самом деле это эквивалентно:
public interface Component extends Annotation{...}
и@interface
Его можно рассматривать как синтаксический сахар.
Элементы аннотации
Мы все еще видим@Component
Этот пример:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
В определении аннотации есть несколько аннотаций.@Target, @Retention, @Documented
,называетсяметааннотация.
Так называемая мета-аннотация - это аннотация, которая описывает аннотацию, которая похоже наPython
метакласс в .
Java
Имеются следующие мета-аннотации:
@Target
Как следует из названия, эта аннотация идентифицирует объект, к которому применяется измененная аннотация. Давайте посмотрим на его исходный код:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
Как видите, значение этой аннотации является массивом, что означает, что аннотация может иметь несколько объектов.
Его ценностный диапазонElementType
Среди этого перечисления:
public enum ElementType {
/** 类、接口、枚举定义 */
TYPE,
/** 字段,包括枚举值 */
FIELD,
/** 方法 */
METHOD,
/** 参数 */
PARAMETER,
/** 构造方法 */
CONSTRUCTOR,
/** 局部变量 */
LOCAL_VARIABLE,
/** 元注解 */
ANNOTATION_TYPE,
/** 包定义 */
PACKAGE...
}
Различные значения представляют диапазон, который может быть изменен путем аннотации, напримерTYPE
Можно декорировать только определения класса, интерфейса и перечисления. Существует особое значение, называемоеANNOTATION_TYPE
, специально для мета-аннотаций.
оглядываясь назад@Component
Этот пример,Target
ценностьTYPE
. Знаком сSpring Boot
Одноклассники тоже должны знать,@Component
Его действительно нельзя размещать перед методами или свойствами.
@Retention
@Retention
Аннотации определяют время жизни декорируемой аннотации. Определяется следующим образом:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
Вы можете увидеть эту аннотацию с помощью одногоRetentionPolicy
Значение перечисления:
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
-
SOURCE
Указывает, что аннотация видна во время компиляции и удаляется после компиляции. Эта аннотация обычно используется для выполнения каких-либо действий в компиляторе; -
CLASS
Указывает, что файл класса записывается после компиляции, но отбрасывается после загрузки класса. Эта аннотация обычно используется для выполнения каких-либо действий на этапе загрузки класса; -
RUNTIME
Это означает, что аннотация всегда будет работать.
@Documented
Эта аннотация относительно проста и указывает, следует ли добавлять кjava doc
середина.
@Inherited
Это также относительно просто, указывая, наследуется ли аннотация. Эта аннотация не очень часто используется.
Примечание. Мета-аннотации используются только при определении аннотаций!
Аннотированная схема
Как вы можете видеть из вышеуказанных мета-аннотаций, аннотация может быть связана с несколькимиElementType
, но только одинRetentionPolicy
:
Встроенные аннотации Java
В Java есть три широко используемых встроенных аннотации, на самом деле, я думаю, что каждый их использовал или видел. Но разобравшись с истинным лицом аннотаций, давайте познакомимся с ними заново!
@Override
Он определяется как:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
Видно, что эта аннотация не имеет никакого значения, она может только модифицировать метод, а RetentionPolicy имеет значение SOURCE, что указывает на то, что это аннотация, которая работает только на этапе компиляции.
Его реальная роль должна быть известна всем, то есть на этапе компиляции, если метод класса@Override
Модифицированный, компилятор проверит, есть ли в его родительском классе функция с такой же сигнатурой, если нет, то скомпилирует ошибку. Видно, что это действительно аннотация, которая бесполезна, кроме как на этапе компиляции.
@Deprecated
Он определяется как:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
Эта аннотация также не имеет никакого значения, он может изменить все типы, и он существует навсегда. Целью этой аннотации - рассказать пользователю, что модифицированный код устарел и может быть удален в следующей версии программного обеспечения. Эта аннотация служит только механизмом уведомления. Если код вызывает код, украшенный @deprected, компилятор выводит предупреждение о компиляции при компиляции.
@SuppressWarnings
Он определяется как:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
* The set of warnings that are to be suppressed by the compiler in the
* annotated element. Duplicate names are permitted. The second and
* successive occurrences of a name are ignored. The presence of
* unrecognized warning names is <i>not</i> an error: Compilers must
* ignore any warning names they do not recognize. They are, however,
* free to emit a warning if an annotation contains an unrecognized
* warning name.
*
* <p> The string {@code "unchecked"} is used to suppress
* unchecked warnings. Compiler vendors should document the
* additional warning names they support in conjunction with this
* annotation type. They are encouraged to cooperate to ensure
* that the same names work across multiple compilers.
* @return the set of warnings to be suppressed
*/
String[] value();
}
Эта аннотация имеет значение массива строк, которое необходимо передать, когда мы используем аннотацию. Его можно использовать перед типами, свойствами, методами, параметрами, конструкторами и локальными переменными Цикл объявления — это время компиляции.
Основная функция этой аннотации — подавить предупреждения компиляции.
Например
public static void main(String[] args) {
Date date = new Date(2020, 5, 22);
}
Мы видим, что,Date
Этот конструктор изменен @deprected:
@Deprecated
public Date(int year, int month, int date) {
this(year, month, date, 0, 0, 0);
}
Таким образом, приведенный выше код сообщит оWarning
:
java: java.util.Date 中的 Date(int,int,int) 已过时
Чтобы не дать компилятору вывести этоWarning
, необходимо использовать вышеуказанноеmain
добавить один перед методом@SuppressWarnings
аннотация:
@SuppressWarning(value = "deprecated")
public static void main(String[] args) {
Date date = new Date(2020, 5, 22);
}
Аннотировать входную строкуdeprecated
Указывает, что компилятор игнорирует@Deprecated
Предупреждения компиляции, вызванные аннотациями.
Резюме и уведомление
Эта статья в основном вводитJava
Суть, элементы и метааннотации аннотаций, триJava
Встроенные аннотации.
Следующиймы будем стоятьJVM
С точки зрения углубленного анализа функционального принципа реализации аннотаций и напишите собственную заметку.