Java аннотации - это один из главных инструментов
метапрограммирования в языке джава (другой интрумент -параметризируемые
классы(=шаблоны=Generics).
Аннотации могут использоваться:
Аннотации начинаются с символа @, что означает AT = Annotation Type. В них могут быть параметры:
Значения:
Значения также записуются короче:
Также аннотации могут быть без значений(такие аннотации называются маркерами):
Есть стандартные(встроенные) аннотации, можно также создавать свои собственные.
Встроенных аннотаций 7:
Вот стандартные аннотации предназанченые для компилятора:
@Deprecated - эта аннотации стала использовать в паре с параметром @deprecated в javadoc комментариях, компилятор выводит предупреждение, когда такой метод используется.
@Override - ставится перед методом, который мы перегружаем в родительском классе. Если мы сделали ошибку в имени, в параметрах или в возвращаемом типе (тоесть метод новый, а не точно такой же как родительский), то компилятор выдаст предупреждение об этом
@SuppressWarnings - служит для подавления предупреждений определенной категории (deprecated, unchecked - когда параметр в Generics не проверяется, fallthrough - когда в свитч-кейсе нет где-то в кейсе брейка).
Можно также подавлять несколько категорий одновременно:
Сейчас приведем пример кастомной аннотации
Чтобы создать аннотацию ей нужно описать аннотационный интерфейс.
Прежче чем это сделать, нужно напомнить что бывают матаданные для метаданных(аннотации для аннотаций), называются они мета-аннотациями(meta-annotation type). Наиболее часто встречаемая мета-аннотация Retention, которая дает компилятору знать до какого этапа деражть аннотацию:
А вот и сам пример:
А вот пример примения этой мета-аннотации в декларации самой этой анноатации:)
Применение мета-аннотации @Inherited. Эта мета-аннотация позволяет унаследывать аннотации суперкласса его подклассам. Пример:
Применение мета-аннотации @Documented. Помеченные так аннотации будут поподать в документацию, сгенерированную javadoc утилитой:
Аннотации могут использоваться:
- компилятором - чтобы диагности ровать ошибки или подавить предупреждения на этапе копиляции.
- на этапе компиляции и развертывания - чтобы сгенерировать код, хмл и другие ресурсы.
- на этапе выполнения - чтобы выполнять рефлективную адаптацию приложения.
Аннотации начинаются с символа @, что означает AT = Annotation Type. В них могут быть параметры:
@Author(
name = "Benjamin Franklin",
date = "3/27/2003"
)
class MyClass() { }
Значения:
@SuppressWarnings(value = "unchecked")
void myMethod() { }
Значения также записуются короче:
@SuppressWarnings("unchecked")
void myMethod() { }
Также аннотации могут быть без значений(такие аннотации называются маркерами):
@Override
void mySuperMethod() { }
Есть стандартные(встроенные) аннотации, можно также создавать свои собственные.
Встроенных аннотаций 7:
- 4 из них из пакета java.lang.annotation: @Retention, @Documented, @Target, and @Inherited. Это мета-аннотации.
- 3 из пакета java.lang: @Override, @Deprecated, and @SuppressWarnings
Вот стандартные аннотации предназанченые для компилятора:
@Deprecated - эта аннотации стала использовать в паре с параметром @deprecated в javadoc комментариях, компилятор выводит предупреждение, когда такой метод используется.
@Override - ставится перед методом, который мы перегружаем в родительском классе. Если мы сделали ошибку в имени, в параметрах или в возвращаемом типе (тоесть метод новый, а не точно такой же как родительский), то компилятор выдаст предупреждение об этом
@SuppressWarnings - служит для подавления предупреждений определенной категории (deprecated, unchecked - когда параметр в Generics не проверяется, fallthrough - когда в свитч-кейсе нет где-то в кейсе брейка).
Можно также подавлять несколько категорий одновременно:
@SuppressWarnings({"unchecked", "deprecation"})
//deprecated method which uses unchecked Generics
Сейчас приведем пример кастомной аннотации
Чтобы создать аннотацию ей нужно описать аннотационный интерфейс.
Прежче чем это сделать, нужно напомнить что бывают матаданные для метаданных(аннотации для аннотаций), называются они мета-аннотациями(meta-annotation type). Наиболее часто встречаемая мета-аннотация Retention, которая дает компилятору знать до какого этапа деражть аннотацию:
- RetentionPolicy.SOURCE - аннотация используется на этапе компиляции и должна отбрасываться компилятором;
- RetentionPolicy.CLASS - аннтоация будет записана в class-файл компилятором, но не будет попадать в запущенное приложение (runtime). Это значение явлется дефолтовым, если не указывать явно эту аннотацию;
- RetentionPolicy.RUNTIME - аннотация будет записана в class-файл и доступна во время выполнения через reflection.
А вот и сам пример:
//определение аннотации
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionRequired {
User.Permission value();
}
public class User {
public static enum Permission {
USER_MANAGEMENT, CONTENT_MANAGEMENT
}
private List permissions;
public List getPermissions() {
return new ArrayList(permissions);
}
// ...
}
//применение определенной аннотации
@PermissionRequired(User.Permission.USER_MANAGEMENT)
public class UserDeleteAction {
public void invoke(User user) { /* */ }
}
//адаптация работы приложения по значению аннотации в момент работы приложения
User user = ...;
Class actionClass = ...;
PermissionRequired permissionRequired = actionClass.getAnnotation(PermissionRequired.class);
if (permissionRequired != null)
if (user != null && user.getPermissions().contains(permissionRequired.value()))
// выполнить действие
Аннотациям можно указывать где они могут использоваться. Это
делается мета-аннотацией @Target, которая может иметь следующие
значения:java.lang.annotation.ElementType.ANNOTATION_TYPE- обьявить создаваемую аннотацию мета-аннотацией(может применяться только возле @interface)java.lang.annotation.ElementType.CONSTRUCTOR- применима только к контрукторам.java.lang.annotation.ElementType.FIELD- применима только к полям классов, в том числе и к константным перечислений(enum).java.lang.annotation.ElementType.LOCAL_VARIABLE- примима только к переменным внутри методов.java.lang.annotation.ElementType.METHOD- применима только к методам.java.lang.annotation.ElementType.PACKAGE- применим только к обьявлению пакета.java.lang.annotation.ElementType.PARAMETER- применима только к параметрам методов.java.lang.annotation.ElementType.TYPE- применима к классам; интерфейсам, в том числе и определяющим аннотации, перечислениям (enum).
А вот пример примения этой мета-аннотации в декларации самой этой анноатации:)
@Documented @Retention(value=RUNTIME) @Target(value=ANNOTATION_TYPE) public @interface Target
Применение мета-аннотации @Inherited. Эта мета-аннотация позволяет унаследывать аннотации суперкласса его подклассам. Пример:
@Inherited
@interface ForEveryone { }
@interface JustForMe { }
@ForEveryone
@JustForMe
class Superclass { }
class Subclass extends Superclass { }
Класс Subclass будет аннотирован @ForEveryone, не не @JustForMe.Применение мета-аннотации @Documented. Помеченные так аннотации будут поподать в документацию, сгенерированную javadoc утилитой:
@interface Secret { }
@Documented
@interface NotSecret { }
@Secret
@NotSecret
public class Example {
}
Конечно же стоит упомянуть применение аннотаций для генерации кода. Это часто используют фреймворки, которые готовы связываться с кастомными классами для предоставления им некого функционала, и понятное дело что им неизвесно за ранее что это за классы будут. Альтернативой аннотаривания таких классов являются ХМЛ-декскрипторы, но я не скажу, что это удлобнее. Вот пример для EJB 3.0: @Entity // Declares this an entity bean
@Table(name = "people") // Maps the bean to SQL table "people"
class Person implements Serializable {
@Id // Map this to the primary key column.
@GeneratedValue(strategy = GenerationType.AUTO) // Database will generate new primary keys, not us.
private Integer id;
@Column(length = 32) // Truncate column values to 32 characters.
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Этот код компилируется и деплоится в среду EJB 3.0, которая уже исполняется, и на этапе исполнения эти аннотации новопродеплоенного класса считываются и по них создается ORM-обьект.
Комментариев нет:
Отправить комментарий