English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Обзор
Java в версии 1.5 ввел аннотации Annotation, также известные как Java-метки, аннотации - это метаданные, которые могут быть напрямую использованы в исходном коде, классы/методы/вариабли/параметры/имена пакетов могут быть помечены аннотациями. В отличие от тегов Javadoc, компилятор может сохранить код аннотаций при создании файла class, а также, возможно, чтобы аннотации могли быть использованы в процессе выполнения программы (run-time), виртуальная машина Java сохраняет аннотации, что позволяет получить информацию о связанных с аннотациями Annotation с помощью reflection.
Встроенные аннотации
На самом деле мы часто встречаем аннотации в повседневной жизни, например, @Override, @Deprecated и т.д., это内置的 аннотации в JDK. Давайте сначала посмотрим, какие основные аннотации встроены в Java.
•Аннотации, действующие на Java-код
◦@Override проверяет, является ли метод переписанным, если этот метод не найден в родительском классе или реализованном интерфейсе, процесс компиляции выдаст ошибку.
◦@Deprecated маркирует метод или класс как устаревший, если используется этот класс или метод, процесс компиляции выдаст предупреждение
◦@SuppressWarnings уведомляет компилятор о том, что нужно игнорировать предупреждения о параметрах, помеченных аннотацией
◦@SafeVarargs игнорирует предупреждения о вызове методов или конструкторов с параметрами generics, аннотация добавлена в версии 1.7
◦@FunctionalInterface указывает, что объявленный интерфейс будет использоваться в качестве функционального интерфейса, аннотация добавлена в версии 1.8
•Аннотации, предназначенные для других аннотаций, называются метаннотациями (Meta Annotation)
◦@Retention указывает, когда использовать помеченный аннотацией (то есть когда аннотация будет сохраняться)
■Оставляются только в исходном коде, выбрасываются в процессе компиляции (RetentionPolicy.RUNTIME)
■Аннотации сохраняются в файл class в процессе компиляции и игнорируются при загрузке файла class (RetentionPolicy.CLASS)
■Аннотации читаются при загрузке файла class, то есть аннотации доступны в процессе выполнения, информацию о аннотациях можно получить через рефлексию (RetentionPolicy.RUNTIME)
◦@Documented указывает, что помеченный аннотацией будет записан в документацию Javadoc при её генерации
◦@Target указывает на область действия помеченного аннотацией
■ElementType.TYPE: используется для описания класса, интерфейса (включая тип аннотации) или объявления enum
■ElementType.FIELD: используется для описания поля
■ElementType.METHOD: используется для описания метода
■ElementType.PARAMETER: используется для описания параметра
■ElementType.CONSTRUCTOR: используется для описания конструктора
■ElementType.LOCAL_VARIABLE: используется для описания локальной переменной
■ElementType.ANNOTATION_TYPE: используется для описания аннотации
■ElementType.PACKAGE: используется для описания пакета
◦@Inherited указывает, что помеченный аннотацией является наследуемым, то есть, если аннотация,修饰анная @Inherited, используется в классе, то эта аннотация также будет действовать на подкласс.
◦@Repeatable указывает, что аннотация, помеченная этим, может применяться多次 к одному и тому же объекту,新增 в версии 1.9
Пользовательские аннотации
Как уже говорилось, столько аннотаций, внимание уделяется мета-аннотациям, при создании пользовательских аннотаций мы обычно используем мета-аннотации для协助 нас. Формат пользовательских аннотаций: public @interface имя_аннотации {body} при использовании @interface для создания аннотации автоматически наследуется интерфейс java.lang.annotation.Annotation. При создании пользовательских аннотаций нельзя наследовать другие аннотации или интерфейсы. Методы, объявленные в аннотации, фактически объявляют параметр аннотации, имя метода является именем параметра, тип возвращаемого значения является типом параметра, можно использовать default для объявления значения по умолчанию для параметра.
Создание пользовательских аннотаций очень просто, использование @interface для определения аннотации, как показано ниже.
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface ClassInfo { String author() default "Wang"; String date(); String comments(); }
Была создана пользовательская аннотация ClassInfo, по @Retention можно понять, что эта аннотация всегда существует, то есть в процессе выполнения программы, эта аннотация все еще действительна; @Target(ElementType.TYPE) означает, что аннотация ClassInfo действует на классы, интерфейсы или enum declarations; @Documented
Объяснение информации ClassInfo может быть записано в документацию Javadoc.
Теперь посмотрим на некоторые параметры аннотации в пользовательских аннотациях, в них три параметра аннотации, параметры аннотации могут быть установлены с значением по умолчанию, например, параметр аннотации author, значение по умолчанию Wang, другие два параметра не имеют значения по умолчанию.
Теперь посмотрим на другую пользовательскую аннотацию.
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MethodInfo { String description() default "No Description"; String date(); }
Эта пользовательская аннотация MethodInfo действует на метод, в процессе выполнения программы, эта аннотация также существует; внутри нее есть два параметра аннотации.
Определение параметров аннотации (определение метода), можно использовать только два доступа修饰ителя public или default, тип параметра поддерживает следующие виды.
•Восьмь основных типов данных (byte, int, short, long, float, double, char, boolean)
•Тип String
•Тип Class
•Тип enum
•Тип Annotation
•Все типы массивов
Использование аннотаций
Кроме вышеупомянутых двух аннотаций, был добавлен еще один аннотация для области действия Field.
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface FieldInfo { String type(); String name(); }
Если параметры аннотации в пользовательских аннотациях не объявлены с значением по умолчанию, при использовании пользовательских аннотаций эти параметры должны быть присвоены,否则 компилятор выдаст ошибку.
Посмотрим на код использования аннотаций:
@ClassInfo(author = "wang", date = "2016/9/13", comments = "annotation demo") public class AnnotationDemo { @FieldInfo(type = "public", name = "firstField") public int firstField; @FieldInfo(type = "private", name = "secondField") private String secondField; @MethodInfo(description = "method in AnnotationDemo", name = "firstMethod") public void firstMethod(String value) { System.out.printf("first method involved"); } @MethodInfo(description = "method in AnnotationDemo", name="secondMethod") private void secondMethod() { System.out.printf("first method involved"); } }
Получение информации о аннотациях
Чтобы получить информацию о аннотациях, сначала нужно убедиться, что аннотация существует в процессе выполнения программы, поэтому обычно к пользовательским аннотациям добавляется метаннотация @Retention(RetentionPolicy.RUNTIME), чтобы в процессе выполнения программы мы могли использовать рефлексию для получения информации о аннотациях. О рефлексии можно узнать из этой статьи.
public class AnnotationTest { public static void main(String[] args) { solveClassAnnotationInfo(AnnotationDemo.class); solveFieldAnnotationInfo(AnnotationDemo.class); solveMethodAnnotationInfo(AnnotationDemo.class); } private static void solveClassAnnotationInfo(Class<?> clz) { // Определение наличия аннотации ClassInfo у класса if(clz.isAnnotationPresent(ClassInfo.class)) { ClassInfo classInfo = (ClassInfo) clz.getAnnotation(ClassInfo.class); System.out.println(classInfo.author() + " " + classInfo.comments() + " " + classInfo.date()); } } private static void solveFieldAnnotationInfo(Class<?> clz) { Field[] поля = clz.getDeclaredFields(); for (Field поле : поля) { if(field.isAnnotationPresent(FieldInfo.class)) { FieldInfo fieldInfo = (FieldInfo) field.getAnnotation(FieldInfo.class); System.out.println(fieldInfo.type() + " " + fieldInfo.name()); } } } private static void solveMethodAnnotationInfo(Class<?> clz) { Метод[] методы = clz.getDeclaredMethods(); for (Метод метод : методы) { if(method.isAnnotationPresent(MethodInfo.class)) {}} MethodInfo methodInfo = (MethodInfo) method.getAnnotation(MethodInfo.class); System.out.println(methodInfo.name() + " " + methodInfo.description()); } } } }
Получение Field/Method и т.д. из класса через reflection, получение связанных аннотаций через getAnnotation() или getAnnotations(), получение конкретной аннотации позволяет получить конкретную информацию.
Результат выполнения выводится следующим образом:
Рис. - 1 График выполнения
Обобщение
Для начинающих Java и даже для разработчиков Java с опытом, контакт с аннотациями Java может быть не очень частым, и на практике они используются редко, но их можно часто встретить в коде. Эта статья является简要介绍注解, по крайней мере, легко читается на уровне кода.
Вот и все, что есть в этой статье, надеюсь, это поможет вам в изучении. Также希望大家多多支持呐喊教程。
Заявление: содержимое этой статьи взято из Интернета, авторские права принадлежат соответствующему автору, материал был предоставлен пользователями Интернета в добровольном порядке и загружен самостоятельно, сайт не обладает правами собственности, материал не был отредактирован вручную, и сайт не несет ответственности за соответствующие юридические вопросы. Если вы обнаружите материалы,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (во время отправки письма замените # на @) для сообщения о нарушении,并提供 соответствующие доказательства. Если после проверки будет установлено, что материал нарушает права на интеллектуальную собственность, сайт немедленно удалят涉嫌侵权的内容。