№13. Annotation & Reflection Flashcards
Что такое аннотация?
Это языковое средство, позволяющее встраивать справочную информацию в исходные файлы. Эта информация называется аннотацией и не
меняет порядок выполнения программы. Это означает, что аннотация сохраняет неизменной семантику программы. Но эта информация может быть использована различными инструментальными средствами на стадии разработки или развертывания прикладных программ на Java. Например, аннотация может обрабатываться
генераторами исходного кода. Для обозначения этого языкового средства служит также термин метаданные. Аннотации создаются с помощью механизма, основанного на интерфейсе.
@interface MyAnno {
String str();
int val();
}
Все аннотации состоят только из объявлений методов и эти методы ведут себя аналогично
полям.
Объявление аннотации не может включать в себя ключевое слово extends. Но все аннотации автоматически расширяют интерфейс Annotation.
В интерфейсе Annotation переопределяются методы hashCode (), equals () и toString (), определенные в классе Object. В нем также объявляется метод annotationType (), возвращающий
объект типа Class, представляющий вызывающую аннотацию.
Аннотацию можно связать с любым объявлением. Например, аннотировать можно классы, методы, поля, параметры и константы перечислимого типа. Аннотированной может быть даже сама аннотация.
Одночленные аннотации - одночленная аннотация состоит из единственного члена. Она действует подобно обычной аннотации, за исключением того, что допускает сокращенную форму указания значения члена. Когда в такой аннотации присутствует только один член, достаточно задать его значение, а когда она применяется, указывать
имя ее члена необязательно. Но для применения этой сокращенной формы единственный член аннотации должен иметь имя value.
Какие аннотации вы знаете в JDK, для чего они нужны?
9 основных встроенных аннотаций:
4- java.lang.annotation: @Retention, @Docurnented, @Target и @Inherited.
5 - java.lang.: @Override, @Deprecated, @Functionallnterface, @SafeVarargs @SuppressWarnings
———————————————————————————–
@Retention
Предназначена для применения только в качестве аннотации к другим аннотациям. Она определяет правило удержания (SOURCE,CLASS и RUNTIME)
@Documented
Служит маркерным интерфейсом, сообщающим инструментальному средству разработки, что аннотация должна быть документирована. Она предназначена для применения только в качестве аннотации к объявлению другой аннотации.
@Target
Задает типы элементов, к которым можно применять аннотацию. Она предназначена
для применения только в качестве аннотации к другим аннотациям.
Аннотация @Target принимает один аргумент, который должен быть константой
из перечисления ElementType. Этот аргумент задает типы объявляемых элементов,
к которым можно применять аннотацию.
@Inherited
Это маркерная аннотация, которую можно применять только в другом объявлении аннотации. Более того, она оказывает воздействие только на те аннотации,
которые будут применяться в объявлениях классов. Аннотация @Inherited обусловливает наследование аннотации из суперкласса в подклассе.
@Override
Это маркерная аннотация, которую можно применять только в методах. Метод, аннотированный как
@Override, должен переопределять метод из суперкласса. Если он этого не сделает, во время компиляции возникнет ошибка. Эта аннотация
служит для гарантии того, что метод из суперкласса будет действительно переопределен, а не просто перегружен.
@Deprecated
Эта маркерная аннотация обозначает, что объявление устарело и должно быть заменено более новой формой. Начиная с версии JDK 9, аннотация @Deprecated позволяет также указать версию Java, с которой аннотируемый элемент считается не рекомендованным к употреблению и подлежит удалению.
@Functionalinterface
Эта маркерная аннотация предназначена для применения в интерфейсах. Она обозначает, что аннотируемый интерфейс является функциональным, т.е. содержит один и только один абстрактный метод.
@SafeVarargs
Это маркерная аннотация применяется в методах и конструкторах. Она указывает на отсутствие каких-нибудь небезопасных действий, связанных с параметром переменной длины.
@SuppressWarnings
Эта аннотация обозначает, что следует подавить одно или несколько предупреждений, которые могут быть выданы компилятором. Подавляемые предупреждения указываются по имени в строковой форме.
Расскажите про Target и Retention?
@Retention является встроенной аннотацией Java: определяет правило удержания аннотации:
Правила удержания определяют момент, когда аннотация отбрасывается. В Java определены три таких правила, инкапсулированные в перечисление
java.lang.annotation.RetentionPolicy. Это правила SOURCE,CLASS и RUNTIME. Аннотации по правилу удержания SOURCE хранятся только в исходном файле и отбрасываются при компиляции. Аннотации по правилу удержания CLASS сохраняются
в файле с расширением .class во время компиляции. Но они недоступны для виртуальной машины JVM во время выполнения. Аннотации по правилу
удержания RUNTIME сохраняются в файле с расширением .class во время компиляции и остаются доступными для виртуальной машины JVM во время выполнения. Это означает, что правило удержания RUNTIME предоставляет аннотации наиболее высокую степень сохраняемости. Если для аннотации не указано никакого правила удержания, то применяется
правило удержания CLASS.
————————————————————————————-
@Target
Задает типы элементов, к которым можно применять аннотацию. Она предназначена для применения только в качестве аннотации к другим аннотациям.
Аннотация @Target принимает один аргумент, который должен быть константой из перечисления ElementType (можно задать одно или несколько значений этих констант). Этот аргумент задает типы объявляемых элементов, к которым можно применять аннотацию.
ElementType.TYPE, означает что она может быть объявлена перед классом, интерфейсом или enum. Объявление @Target в любых других местах программы будет воспринято компилятором как ошибка.
Остальные возможные типы аннотации @Target:
PACKAGE - назначением является целый пакет (package);
TYPE - класс, интерфейс, enum или другая аннотация:
METHOD - метод класса, но не конструктор (для конструкторов есть отдельный тип CONSTRUCTOR);
PARAMETER - параметр метода;
CONSTRUCTOR - конструктор;
FIELD - поля-свойства класса;
LOCAL_VARIABLE - локальная переменная (обратите внимание, что аннотация не может быть прочитана во время выполнения программы, то есть, данный тип аннотации может использоваться только на уровне компиляции как, например, аннотация @SuppressWarnings);
ANNOTATION_TYPE - другая аннотация.
TYPE_PARAMETER - тип параметра
TYPE_USE - везде, где применяются типы данных (тип, возвращаемый методом, тип объекта по ссылке this в теле метода, приведение типов, уровни доступа к массиву, наследуемый класс, оператор throws, а также обобщенные типы, включая границы параметров и аргументы обобщенного типа)
Какие свойства возможны в аннотациях?
- Все аннотации состоят только из объявлений методов (без аргументов) и эти методы ведут себя аналогично полям.
- методы аннотаций могут иметь значение по умолчанию (default в объявлении члена аннотации.)
Атрибуты могут иметь только следующие типы:
- примитивы
- String
- Class или «any parameterized invocation of Class»
- enum
- одномерный массив элементов любого из вышеперечисленных типов
Что такое рефлексия?
Рефлексия - это языковое средство для получения сведений о классе во время выполнения программы.
Прикладной программный интерфейс (API) для рефлексии входит в состав пакета
java.lang.reflect.
Воспользовавшись рефлексией можно получить объект типа Class. Самый простой способ - вызвать
метод getClass (),определенный в классе Object. Этот метод возвращает объект типа Class, который представляет вызывающий объект.
Имея в своем распоряжении объект типа Class, можно воспользоваться его методами для получения сведений о различных элементах, объявленных в классе (getMethod (), getField () и getConstructor ()). Из объекта типа Class, Method, Field или Constructor можно получить конкретные аннотации, связанные с этим объектом, вызвав метод getAnnotation ().
Для того чтобы получить сразу все аннотации, имеющие аннотацию @Retention
с установленным правилом удержания RUNTIME и связанные с искомым элементом,
достаточно вызвать метод getAnnotations () для этого элемента. Метод getAnnotations () возвращает массив аннотаций. Этот метод может
быть вызван для объектов типа Class, Method, Constructor и Field.
Методы getAnnotation () и getAnnotations () определены в интерфейсе AnnotatedElement, который входит в состав пакета java.lang.reflect. Этот интерфейс поддерживает рефлексию для аннотации и реализуется в классах Method, Field, Constructor, Class
и Package. Кроме методов getAnnotation () и getAnnotations (), в интерфейсе
AnnotatedElement определяются два других метода. Первый метод, getDeclaredAnnotations (),имеет следующую общую форму:
Annotation[] getDeclaredAnnotations()
Данный метод возвращает ненаследуемые аннотации, присутствующие в вызывающем
объекте. А второй метод, isAnnotationPresent (),имеет такую общую форму:
boolean isAnnotationPresent(Class extends Annotation>
тип_ аннотации)
Этот метод возвращает логическое значение true, если аннотация, заданная в виде аргумента тип_ аннотации, связана с вызывающим объектом. В противном
случае возвращается логическое значение false. В версии JDK 8 эти методы дополнены методами getDeclaredAnnotation (), getAnnotationsByType ()
и getDeclaredAnnotationsByType ()
Что можно сделать с помощью рефлексии и как? Описать общими словами
Для реализации какого-то инструмента, который на основе рефлексии и, допустим аннотаций, будет решать определённую задачу