Аннотация Java (Аннотация)
0.0 Hello World
Сначала закодируй, потом объясни. Это не смутит новичков.
public class Dog extends Animal(){
@Override
public void call(){
System.out.println("汪汪...");
}
}
0.1 Java поставляется с аннотациями - @Override
@Override, объявленный в методе call(), представляет собой аннотацию, поставляемую с Java, и ее функция состоит в том, чтобы пометить метод как переопределенный. Когда класс или интерфейс, который наследует класс, не имеет этого метода, во время компиляции будет сообщено об ошибке, потому что целью объявленной вами аннотации является переопределение метода. Другой эффект заключается в том, что этот метод также отображает @Override в сгенерированном javadoc, чтобы указать, что этот метод переопределен.
0.2 Аннотации просто предоставляют описание кода
По-видимому, @Override не влияет на выполнение вашего кода. Если вы удалите комментарий, код все равно будет работать нормально. Таким образом, мы приходим к выводу: аннотации Java просто предоставляют описания для элементов кода (классы, методы, параметры методов и т. д.).
0.3 Обработка аннотаций
Увидев это, вы можете подумать, что аннотации не бесполезны, но подумайте, об упомянутой выше ошибке компиляции будет сообщено, в чем дело. Хотя в самом аннотировании нет никакой логики, вы аннотируете его, чтобы помочь другим программам выполняться. Здесь вы аннотировали @Override, и это будет оценено, когда вы обнаружите, что аннотировали этот метод во время компиляции.
К настоящему времени у вас есть общее представление о том, для чего используются аннотации. Ниже представлена часть корпуса, в которую входят:
- пользовательская аннотация
- Java поставляется с аннотациями
- Процессор аннотаций
1.0 Пользовательские аннотации
1.1 Метааннотации
Давайте откроем исходный код @Override, чтобы увидеть:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
Исходный код аннотации очень прост, как и определение интерфейса. Он объявляет, что это аннотация с оформлением @interface. Кроме того, есть еще две аннотации @Target и @Retention, Мы называем эти аннотации мета-аннотациями, которые используются только для пользовательских аннотаций.
@Target
@Target указывает, где можно использовать определяемую вами аннотацию. включать:
Типы | описывать |
---|---|
ElementType.ANNOTATION_TYPE | Аннотация может быть аннотирована |
ElementType.CONSTRUCTOR | Метод строительства |
ElementType.FIELD | атрибут класса |
ElementType.LOCAL_VARIABLE | локальная переменная |
ElementType.METHOD | метод |
ElementType.PACKAGE | Сумка |
ElementType.PARAMETER | параметры метода |
ElementType.TYPE | Классы, интерфейсы, перечисления и т.д. |
Можно заполнить несколько, используйте формат массива{}
приложить и использовать,
разделены.
@Retention
@Retention указывает область пользовательской аннотации. необязательный
Типы | описывать |
---|---|
RetentionPolicy.SOURCE | Работает только в исходном коде |
RetentionPolicy.CLASS | Исходный код и функция времени компиляции |
RetentionPolicy.RUNTIME | Исходный код, время компиляции и время выполнения — все работает |
Есть также две необязательные мета-аннотации
@Documented
Указывает, что текущие пользовательские аннотации также включаются при создании javadoc.
@Inherited
Указывает, что текущая аннотация может быть унаследована. Но это не означает наследование пользовательских аннотаций, это означает, что когда класс наследует класс, использующий эту аннотацию, аннотация также наследуется.
1.2 Атрибуты аннотации
Далее давайте взглянем на более сложный исходный код аннотаций, который является исходным кодом Spring @Bean:
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
@AliasFor("name")
String[] value() default {};
@AliasFor("value")
String[] name() default {};
Autowire autowire() default Autowire.NO;
String initMethod() default "";
String destroyMethod() default "(inferred)";
}
Самая большая разница между этой аннотацией и приведенной выше заключается в том, что в теле аннотации гораздо больше методов. На самом деле это не методы, а атрибуты аннотаций. С помощью этих свойств мы можем дополнительно описать код.
Формат определения атрибута аннотации:类型 属性名() default 初始值;
.
- Атрибуты аннотации ограничены типами и могут быть только следующих типов:
- 8 основных типов
- Class
- String
- enum (Autowire выше - это тип перечисления)
- Annotation
- или форма массива вышеуказанных типов
- по умолчанию является модификатором, и
=
аналогичный; - Начальное значение не равно null, поэтому выше мы видим, что тип String использует пустую строку.
""
; - Кроме того, если аннотация имеет только один параметр, имя атрибута должно быть значением.
При использовании аннотаций вы можете использовать мета-аннотацию @Target, как указано выше.()
заключается в заполнении свойств.
- Если есть только один атрибут, заполните его напрямую. То есть атрибут value() аннотации;
- Если необходимо использовать несколько
@Target(属性名=属性值,属性名=属性值)
заполнить форму;
2.0 Java поставляется с аннотациями
Собственные аннотации Java очень просты, их всего три.
@Override
Метод, используемый для маркировки, переопределен. Рекомендуется отмечать переопределенные методы, что поможет читателям и IDE указать на ваши ошибки.
@Deprecated
Используется для объявления помеченного кода истекающим, не рекомендуется. Во время компиляции вы получите ошибки, приводящие к сбою компиляции. Может быть помечен в тегах, отличных от ANNOTATION_TYPE.
@SupressWarning
Хотя он помечен @Deprecated, компиляция будет неправильной. В то время программный код, который иногда был длинным, должен был использовать этот класс. Можно использовать аннотацию @SupressWarning, чтобы игнорировать @Deprecated, что приводит к ошибкам компиляции.
Обработка аннотаций
В начале мы сказали, что аннотации предоставляют только описания кода, но другие программы могут использовать эти данные описания, чтобы определить, следует ли выполнять операцию. Обработка аннотаций выполняется с использованием отражения Java.
Примечание: Краткое описание рефлексии.
Классы, методы, атрибуты экземпляра и т. д. сами по себе являются объектами.Например, какие модификаторы определены классом, какие у него есть методы, какие атрибуты экземпляра и какие аннотации. Таким образом, каждый класс на самом деле является экземпляром типа класса Java. С помощью класса вы можете понять все о самом классе или управлять некоторыми конкретными функциями.
Например, у нас есть несколько классов животных, и мы создаем пользовательскую аннотацию @Animal для представления их характеристик, таких как количество ног, кусаться или нет.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnimalTrait{
int footNum() default 0;
boolean bitePeople default false;
}
животное
@AnimalTrait(footNum=4,bitePeople=true)
class Dog extends Call{
public void call(){
System.out.println("汪汪...");
}
}
@AnimalTrait(footNum=4,bitePeople=false)
class Cat extends Animal{
public void call(){
System.out.println("喵喵...");
}
}
@AnimalTrait(footNum=2,bitePeople=false)
class Monkey extends Animal{
public void call(){
System.out.println("吖吖...");
}
}
//...其他动物类
Предположим, у нас есть коллекция зоопарка, содержащая экземпляры всех животных. Теперь мы собираемся написать класс для разделения кусающих и некусающих животных в единый набор, чтобы управлять ими.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Animal> zooAnimal = new ArrayList<>();
ArrayList<Animal> biteList = new ArrayList<>();
ArrayList<Animal> notbiteList = new ArrayList<>();
for(int i=0;i<8;i++){
zooAnimal.add(new Cat());
zooAnimal.add(new Dog());
}
for(Animal animal:zooAnimal){
//主要部分,获取实例对应类型的@AnimalTrait注解的bitePeople属性
if(animal.getClass().getAnnotation(AnimalTrait.class).bitePeople()){
biteList.add(animal);
} else {
notbiteList.add(animal);
}
}
System.out.println("咬人的动物叫声:");
for(Animal animal:biteList){
animal.call();
}
System.out.println("不咬人的动物叫声:");
for(Animal animal:notbiteList){
animal.call();
}
}
}
Основная часть состоит в том, чтобы получить информацию об аннотации.В условии используйте getClass для получения экземпляра Class класса экземпляра, затем используйте getAnnotation() для получения экземпляра Annotation @AnimalTrait класса и, наконец, получите значение атрибута аннотацию через .bitePeople().
Интерфейс AnnotatedElement
Все типы отражения Class, Constuctor, Method, Field и т. д. наследуют интерфейс AnnotatedElement. Основная функция интерфейса — получить тип отражения аннотации, а затем получить атрибуты аннотации.
Общие методы интерфейса AnnotatedElement
возвращаемое значение | сигнатура метода | описывать |
---|---|---|
<T extends Annotation> T | getAnnotation(Class<T> annotationClass) | Возвращает указанный тип аннотации |
Annotation[] | getAnnotations() | Возвращает массив всех аннотаций |
default boolean | isAnnotationPresent(Class<? extends Annotation> annotationClass) | Определить, есть ли аннотация указанного типа |
Тип аннотации
Мы можем получить тип аннотации с помощью.注解属性名()
способ получить свойства аннотации.
Суммировать
- Аннотации Java предоставляют только описания элементов кода и не влияют на выполнение кода;
- Что влияет на выполнение кода, так это процессор аннотаций, который использует механизм отражения для получения атрибутов аннотаций;
- Определите аннотации через @interface и установите тип аннотаций, жизненный цикл, следует ли генерировать Javadoc и следует ли наследоваться с помощью метааннотаций @Target, @Retention, @Documented и @Inherited.
- Аннотации могут иметь атрибуты, но атрибуты могут быть только в виде массива из 8 основных типов: String, Class, enum, Annotation и выше.