首页 Java 学习 注解
文章
取消

Java 学习 注解

注解

概述

对java中类、方法、成员变量做标记,然后进行特殊处理

例如 junit中 @Test 标记的方法就可以被当作测试方法执行

自定义注解

1
2
3
public @interface 注解名称 {
 public 属性类型 属性名() [default 默认值];
}

可以不标记 public 默认就是public

这里的属性名有一个特殊属性名,value 当只有一个属性为value时,注解时可以不写属性名value,但如果有多个属性名,且没有默认值时,需要写明value这个属性名

Java自定义注解开发_小滦不秃头‍♂️的博客-CSDN博客_java 自定义注解

Java 自定义注解 - MyDistance - 博客园

基本注解

@Override 重写

@Deprecated 已过时

@SuppressWarnings(value=”unchecked”) 压制编辑器警告

元注解

@Retention

定义注解的保留策略

1
2
3
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) //注解会在class字节码文件中存在,在运行时可以通过反射获取到

@Target

定义注解可以放置的位置

1
2
3
4
5
6
7
8
@Target(ElementType.TYPE) //接口、类
@Target(ElementType.FIELD) //属性
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE) //局部变量
@Target(ElementType.ANNOTATION_TYPE) //注解
@Target(ElementType.PACKAGE) //包

多个 用 {} 如 Target({type,field,…})

@Inherited 具有继承性

@Documented 可以被javadoc工具提取成文档

注解解析

基本概念

即判断是否中存在注解,存在注解就解析出内容

注解顶级接口 Annotation

AnnotatedElement 该接口定义了与注解解析相关的解析方法

主要的解析方法:

  • Annotation[] getDeclaredAnnotations() 获取当前对象上的注解数组

  • T getDecalredAnnotation(Class<T> annotationClass) 根据注解类型获取注解对象

  • boolean isAnnotationPresent(Class<Annotation> annotationClass) 判定是否使用指定的注解

所有的类成分Class Method Field Constructor 都是先了AnnotatedElement接口,都拥有解析注解的能力

流程

  1. 先获取指定的对象 比如类对象 方法对象

  2. 判断该对象上是否存在指定的注解

  3. 如果存在 直接获取注解对象

  4. 再对该对象进行操作

举例

这里以类对象和方法对象的注解进行示例

MyBook 自定义注解

1
2
3
4
5
6
7
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface MyBook {
    String name();
    String[] author();
    double price();
}

注解解析测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@MyBook(name="class book",author = {"1","2"},price = 11.1)
public class BookAnnotation {

    @MyBook(name="method book",author = {"3","4"},price = 22.2)
    public void test(){}

    public static void main(String[] args) throws NoSuchMethodException {
        // class annotation test
        // 获取所有annotation 遍历判断当前注解是否为指定注解的实例
        Class<BookAnnotation> c = BookAnnotation.class;
        Annotation[] declaredAnnotations = c.getDeclaredAnnotations();
        for (Annotation declaredAnnotation : declaredAnnotations) {
            if(declaredAnnotation instanceof MyBook){
                MyBook myBook = (MyBook) declaredAnnotation;
                System.out.println(Arrays.toString(myBook.author()));
                System.out.println(myBook.name());
                System.out.println(myBook.price());
            }
        }
        // method annotation test
        // 使用isAnnotationPresent 直接判断当前对象上是否有指定的注解
        // Method[] declaredMethods = BookAnnotation.class.getDeclaredMethods();
        Method test = BookAnnotation.class.getDeclaredMethod("test");
        if(test.isAnnotationPresent(MyBook.class)){
            MyBook myBook = test.getDeclaredAnnotation(MyBook.class);
            System.out.println(Arrays.toString(myBook.author()));
            System.out.println(myBook.name());
            System.out.println(myBook.price());
        }
    }
}

这里用到了 反射 这一技术

本文由作者按照 CC BY 4.0 进行授权

Java 学习 反射

Java 学习 动态代理