注释是给编译器和虚拟机看的,编译器和虚拟机在运行的过程中可以获取注解信息,然后可以根据这些注解的信息做各种想做的事情。比如:大家对@Override应该比较熟悉,就是一个注解,加在方法上,标注当前方法重写了父类的方法,当编译器编译代码的时候,会对@Override标注的方法进行验证,验证其父类中是否也有同样签名的方法,否则报错,通过这个注解是不是增强了代码的安全性。 # 一、注解的使用 ## 1. 定义注解 ### 语法 jdk中注解相关的类和接口都定义在java.lang.annotation包中,注解的定义和我们常见的类、接口类型,只是注解使用@interface来定义,例 public @interface Myannotation{ } ### 注解中定义的参数 ![[Snipaste_2023-02-15_14-12-23.png]] 注解中可以定义多个参数,参数的定义有以下特点: 1. 访问修饰符必须为public,不写默认为public 2. 该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组 3. 该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作) 4. 参数名称后面的 () 不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法 5. default 代表默认值,值必须和第2点定义的类型一致 6. 如果没有默认值,代表后续使用注解时必须给该类型元素赋值 ### 指定注解的使用范围:@Target ![[Snipaste_2023-02-15_14-14-18.png]] 注解可以用在类、接口、注解类型、枚举类型以及方法上面,自定义注解上也可以不使用@Target注解,如果不使用,表示自定义注解可以用在任何地方。 ![[Snipaste_2023-02-15_14-16-05.png]] ### 指定注解的保留策略:@Retention ![[Snipaste_2023-02-15_14-17-35.png]] 如上图指定了注解只存在于源码阶段,后面会丢失 ![[Snipaste_2023-02-15_14-18-47.png]] ## 2.使用注解 ![[Snipaste_2023-02-15_14-20-28.png]] ![[Snipaste_2023-02-15_14-21-05.png]] ![[Snipaste_2023-02-15_14-21-28.png]] 为参数指定默认值 ![[Snipaste_2023-02-15_14-22-26.png]] ![[Snipaste_2023-02-15_14-23-40.png]] ## 3.注解信息的获取 java通过反射获取注解相关信息,在java.lang.reflect下有AnnotatedElement接口,用于表示目前正在虚拟机中运行的程序中已使用注解的元素,通过该接口提供的方法可以利用反射技术读取注解信息 ![[Snipaste_2023-02-15_14-32-52.png]] + Package:用来表示包的信息 + CLass:用来表示类的信息 + Constructor:用来表示构造方法信息 + Field:用来表示类中属性信息 + Method:用来表示方法信息 + Parameter:用来表示方法参数信息 + TypeVariable:用来表示类型变量信息,如:类上定义的范型类型变量,方法上面定义的范型类型变量 ### AnnotatedElement常用方法 ![[Snipaste_2023-02-15_14-36-27.png]]