Главная > Java Standard Edition > Аннотации в Java (java annotation types). Пример 1

Тема Зацепин
268

Java-разработчик 🧩
454
1 минуту

Аннотации в Java (java annotation types). Пример 1

Продолжаю серию статей о нововведениях в Java (начиная с версии 1.5). На этот раз разговор пойдет об аннотациях (annotation type).

Добавлено : 3 Nov 2008, 01:59

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

Вот основные варианты использования аннтоаций:

  • предоставлять необходимую информацию для компилятора;
  • предоставлять метаданные различным инструментам для генерации кода, конфигураций и т.д.;
  • использоваться в коде во время выполнения програмного кода (reflection).

Аннотации могут быть применены, например, к декларациям классов, полей, методов, ну и конечно же аннотаций :).
Для описания новой аннотации используется ключевое слово @interface. Вот банальный пример аннотации:

public @interface Description {
String title();

int version() default 1;

String text
();
}

И пример ее использования:

@Description(title="title", version=2, text="text")
public class Clazz { /* */ }

Сразу хочу обратить ваше внимание - в качестве типов у элементов аннотации могут использоваться только примитивные типы, перечисления и класс String.

Если у аннотации нет элементов, ее называют маркером (marker annotation type). В этом случае при использовании аннотации круглые скобки можно не писать.

В случае, когда аннтоация указывается для другой аннотации, первую называют мета-аннотацией (meta-annotation type).
Достаточно часто вам придется сталкиваться с мета-аннтоацией Retention. Она показывает, как долго необходимо хранить аннтоацию и инициализируется одним из трех значений:

  • RetentionPolicy.SOURCE - аннотация используется на этапе компиляции и должна отбрасываться компилятором;
  • RetentionPolicy.CLASS - аннтоация будет записана в class-файл компилятором, но не должна быть доступна во время выполнения (runtime);
  • RetentionPolicy.RUNTIME - аннотация будет записана в class-файл и доступна во время выполнения через reflection.

Тут есть еще одна вещь, на которую хочу обратить ваше внимание: по умолчанию у всех аннотаций стоит RetentionPolicy.CLASS. Это мне кажется недодумкой. В исходниках JDK очень часто используется эта policy, но вот в разработке нужна именно RetentionPolicy.RUNTIME. К сожалению, ничего уже не поменяется из-за обратной совместимости.

Пришло время привести реальный пример использования аннотаций при программировании на Java.

Предположим, нам нужно ограничить доступ к некоторым функциям веб-приложения для разных пользователей. Иными словами необходимо реализовать права (permissions).
Для этого можно добавить следующее перечисление в класс пользователя:

public class User {
public static enum Permission {
USER_MANAGEMENT, CONTENT_MANAGEMENT
}

private List permissions;

public List getPermissions() {
return new ArrayList(permissions);
}

// ...
}

Создадим аннтоацию, которую затем будем использовать для проверки прав:

@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionRequired {
User.Permission value();
}

Теперь предположим у нас есть некоторое действие, право на выполнение которого мы хотим ограничить, например, UserDeleteAction. Мы добавляем аннтоацию на это действие следующим образом:

@PermissionRequired(User.Permission.USER_MANAGEMENT)
public class UserDeleteAction {
public void invoke(User user) { /* */ }
}

Теперь используя reflection можно принимать решение, разрешать или не разрешать выполнение определенного действия:

User user = ...;
Class> actionClass = ...;
PermissionRequired permissionRequired = actionClass.getAnnotation
(PermissionRequired.class);
if (permissionRequired != null)
if (user != null && user.getPermissions().contains(permissionRequired.value()))
// выполнить действие

Вот и все.

Буду благодарен за любые замечания и комментарии по поводу статьи.
Всего вам хорошего.

Теги: annotationsjava5

Еще от автора

Применение WeakHashmap для списков слушателей

В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.

Заставки в Mustang

Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.

Совмещение изображений

1 Введение 2 Правила визуализации и пример 3 Совмещение изображений в оперативной памяти 4 Постепенное исчезновение изображения 5 Ссылки и дополнительная информация

Еще по теме

Применение WeakHashmap для списков слушателей

В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.

Заставки в Mustang

Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.

Использование потоков

1 Введение 2 Работа с выражениями типа Boolean 3 Класс JoptionPane 4 Приложение-счетчик 5 Ссылки

Перехват необрабатываемых исключений

В статье от 16 марта 2004 года Best Practices in Exception Handling были описаны приемы обработки исключений. В данной статье вы изучите новый способ обработки исключений при помощи класса UncaughtExceptionHandler добавленного в J2SE 5.0.

Использование класса LinkedHashMap

1 Введение 2 Сортировка хэш-таблицы 3 Копирование таблицы 4 Сохранение порядка доступа к элементам 5 Ссылки

Сказ про кодировки и java

С кодировками в java плохо. Т.е., наоборот, все идеально хорошо: внутреннее представление строк – Utf16-BE (и поддержка Unicode была с самых первых дней). Все возможные функции умеют преобразовывать строку из маленького регистра в большой, проверять является ли данный символ буквой или цифрой, выполнять поиск в строке (в том числе с регулярными выражениями) и прочее и прочее. Для этих операций не нужно использовать какие-то посторонние библиотеки вроде привычных для php mbstring или iconv. Как говорится, поддержка многоязычных тестов “есть в коробке”. Так откуда берутся проблемы? Проблемы возникают, как только строки текста пытаются “выбраться” из jvm (операции вывода текста различным потребителям) или наоборот пытаются в эту самую jvm “залезть” (операция чтения данных от некоторого поставщика).