Annotation & Reflection Flashcards

1
Q

Что такое аннотация?

A

Аннотация - это специальные метки ( мета-дата), которая содержит некоторую информацию о программе, но при этом не является частью программы. Аннотации напрямую не влияют на код.

Аннотации создаются с помощью механизма, основанного на интерфейсе.
@interface MyAnno {
String str();
int val();
}
Все аннотации состоят только из объявлений методов и эти методы ведут себя аналогично полям.
Объявление аннотации не может включать в себя ключевое слово extends. Но все аннотации автоматически расширяют интерфейс Annotation.
В интерфейсе Annotation переопределяются методы hashCode (), equals () и toString (), определенные в классе Object. В нем также объявляется метод annotationType (), возвращающий
объект типа Class, представляющий вызывающую аннотацию.

Аннотацию можно связать с любым объявлением. Например, аннотировать можно классы, методы, поля, параметры и константы перечислимого типа. Аннотированной может быть даже сама аннотация.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Какие аннотации вы знаете в JDK, для чего они нужны?

A

Для чего нужны аннотации:
1. Информация для компилятора - аннотации используются компилятором, для обнаружения
ошибок
2. Во время компиляции - специальные инструменты могут использовать аннотации, например,
для генерации кода
3. В runtime - аннотации также могут быть доступны во время выполнения программы

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
Эта аннотация обозначает, что следует подавить одно или несколько предупреждений, которые могут быть выданы компилятором. Подавляемые предупреждения указываются по имени в строковой форме.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Расскажите про Target и Retention?

A

@Retention( где будет доступна) является встроенной аннотацией Java: определяет правило удержания аннотации:
Правила удержания определяют момент, когда аннотация отбрасывается.
SOURCE - аннотация будет хранятся только в исходном файле и отбрасываются при компиляции, не будет доступна в
RUNTIME и .class файлах
CLASS - аннотация будет сохранена в .class файле, но не будет доступна в runtime.
Если не задать RetentionPolicy, то этот тип будет использован по умолчанию
RUNTIME - аннотация будет доступна в runtime (то есть в запущенной программе)
————————————————————————————-
@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, а также обобщенные типы, включая границы параметров и аргументы обобщенного типа)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Какие свойства возможны в аннотациях?

A
Аннотация описывается как обычный интерфейс, но
с ограничениями.
1. У метода не может быть аргументов;
2. Можно определить значение по-умолчанию,
ключевое слово default
3. Тип результата может быть только:
1. Примитивы
2. String
3. Class
4. Enum
5. Массив предыдущих типов
String[] authors();
String description();
String shortDescription();
String since() default "1.7"
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Что такое рефлексия?

A

Reflection (рефлексия) - инструмент для исследования данных о программе во время выполнения. Рефлексия позволяет исследовать информацию о полях,
методах и конструкторах классов.

Можно также выполнять операции над полями и методами, которые исследуются. Рефлексия в Java осуществляется с помощью Java Reflection API. Этот интерфейс API состоит из классов пакетов java.lang и 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 ()

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Что можно сделать с помощью рефлексии и как? Описать общими словами

A
  • Узнать/определить класс объекта;
  • Получить информацию о модификаторах класса, полях, методах, константах, конструкторах и суперклассах;
  • Выяснить, какие методы принадлежат реализуемому интерфейсу/интерфейсам;
  • Создать экземпляр класса, причем имя класса неизвестно до момента выполнения программы;
  • Получить и установить значение поля объекта по имени;
  • Вызвать метод объекта по имени.

java.lang.Class - класс, используя который можно получить всю
информацию о классе.
Получить класс можно несколькими способами:
Main main = new Main();
Class classFromObject = main.getClass();
Class classFromClass = Main.class;
Class classFromReference = Class.forName(“ru.maksaimer.s13.Mai

isAnnotation() - является ли аннотацией
isInterface() - является ли интерфейсом
isArray() - является ли массивом
isPrimitive() - является ли оберткой примитивов
isEnum() - является ли перечислением
getConstructors() - вернёт массив конструкторов (java.lang.reflect.Constructor)
getDeclaredFields() - вернет массив всех полей (java.lang.reflect.Field)
getMethods() - вернет массив всех методов (java.lang.reflect.Method)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly