Аннотации Flashcards
Дефолтные значения полей аннотаций
Если у них нет дефолтных значений, то их значения нужно указывать при аннотировании, иначе ошибка компиляции. Дефолтное значение указывается как String name() default “Current”. При этом дефолтное значение должно быть константой уровня компиляции и не может быть Null.
К чему можно применять аннотации
Аннотации можно применять даже к локальным переменным и в кастинг выражении к кастуемому классу.
Шортхэнды аннотаций
Если имя поля value то его можно опускать при использовании аннотации (если другие поля не используются при этом), в иных случаях названия полей нужно указывать.
Если в аннотации не указан ни один аттрибут то скобки не обязательны
При указывании аттрибута аннотации тип которого массив, если элемент один то скобки {} можно опускать (@Annot(name={“ABC”}) и @Annot(name=“ABC”) ) равноценны
Что может быть внутри аннотаций
Кроме методов и других аннотаций внутри аннотации может быть константы как и в интерфейсах- по сути аннотация очень похожа на интерфейс до введения static/default методов. Аннотации автоматически расширяют интерфейс java.lang.Annotation
@Target
@Target аннотация для аннотаций - указывает на что можно навешивать. По дефолту можно навешивать всюду кроме очень узких мест и параметров.
Используется в формате Target(ElementType.тип блока кода (метод, класс и т.д.)
TYPE, TYPE_USE(почти во всех местах где используются типы, т.е. почти повсюду),METHOD,FIELD(кроме локальных переменных),PARAMETER(в т.ч. конструкторов и лямбд),CONSTRUCTOR,ANNOTATION_TYPE(Только аннотации),PACKAGE(package-info.java),MODULE,TYPE_PARAMETER(дженерики)
Аннотации аннотаций
Аннотации аннотаций:
@Reflection позволяет вытягивать приватные поля и метода
@Retention- аннотация для аннотаций указывает когда аннотация доступна
RetentionPolicy.SOURCE - аннотация присутствует только на этапе компиляции
RetentionPolicy.CLASS (дефолтное поведение)- аннотация записывается в class файл но отрабатывает до RUNTIME
RetentionPolicy.RUNTIME - и записана в class файл и доступна в runtime через reflection
@Target
@Documented -документирует аннотацию в JavaDoc
@Inherited- если аннотация помеченная ей применена к классу то подклассы также наследуют ее (для аннотаций не работает)
@Repeatable
@Repeatable как применять
Аннотацией помеченную как @Repeatable можно помечать несколько раз один и тоже субъект. Однако при аннотировании аннотации, нужно как value указать другую аннотацию- групповую, которая будет иметь value() массив данных аннотаций. (P.S. групповая аннотация нигде не используется кроме как value @Repeatable) Например @Repeatable(Tasks.class) @interface Task{} @interface Tasks {Task[] value[]}
До 8 джавы нужно было бы без использования Repeatable просто использовать такой синтаксис.
@Tasks{@Task(),@Task()}
Примеры основных аннотаций
@Deprecated - имеет параметры since, boolean forRemoval
@Override
@SupressWarnings - ингибирует предупреждения компилятора и позволяет пропустить валидацию ошибки. Может принимать параметр (например “unchecked”) подавляет только непроверяемые предупреждения.
@FunctionalInterface проверяется интерфейс на соответствие его определению функционального. Также маркирует интерфейс в целях документирования
@SafeVarargs- редко используемая аннотация, помечающая что компайлеру не надо жаловаться на проблемы типобезопасности. Можно помечать только методы с вараргами, которые нельзя оверрайдить (private, final, static)