目录
(一)元注解的使用
元注解是用来修饰注解声明的注解,可以控制被修饰的注解的特性。
【1】@Target
用来声明被修饰的注解可以用在什么位置。可以在@Target的属性中设置ElementType类型的数组来指定可以使用的位置。如果不用此元注解修饰,默认注解可以用在任意位置。
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
补充:TYPE表示类,FIELD表示属性
【2】@Retention
用来声明被修饰的注解会被保留到什么阶段。
名称 | 解释 | 备注 |
---|---|---|
RetentionPolicy.SOURCE | 此注解将会被保留到源码阶段.java中,.java中。 在编译过程中被删除。 | 这种类型的注解通常是给编译器看的。 |
RetentionPolicy.CLASS | 此注解将会被保留在源码阶段和编译阶段,.java和.class中。在类加载的过程中被删除。 | 这种类型的注解通常是给类加载器看的。 |
RetentionPolicy.RUNTIME | 此注解将会被保留在源码阶段 、编译阶段 和 运行段。 .java .class和内存中的字节码中都会存在 | 这种类型的注解通常用来在运行阶段进行反射,控制程序运行过程。 |
补充:只有RUNTIME级别的注解才可以通过反射技术进行反射。
【3】@Documented
用来声明被修饰注解是否要被文档提取工具提取到文档中。默认不提取。
【4】@Inherited
被修饰的注解是否具有继承性,默认没有继承性。
(二)注解添加属性
注解中的所有的属性必须是public的,可以显式声明,也可以不声明,不声明默认就是public的。
注解中的属性只能是八种基本数据类型、String类型、Class类型、枚举类型、其他注解类型及以上类型的一维数组。
注解类声明属性的过程非常类似于为接口定义方法。String name();定义name变量
注解中声明的属性,需要在使用注解时,为其赋值,赋值的方式就是使用注解时,在注解后跟一对小括号 在其中通过属性名=属性值的方式指定属性的值。
声明属性的默认值,在声明注解时 在注解的属性后 通过default关键字,声明属性的默认值,声明过默认值的属性 可以在使用注解时不赋值,则默认采用默认值,也可以手动赋值覆盖默认值如果属性是一维数组类型 而 在传入的数组中只有一个值,则包括数组的大括号可以省略,如果注解的属性,只有一个需要赋值 且该属性的名称叫做value 则在使用注解时 value=可以不写
(三)注解的创建
- 创建注解,使用@interface关键字创建
- 添加元注解,设置保存阶段与放置位置
- 添加属性
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE,ElementType.METHOD}) //设置注解放置在类上和方法上
@Retention(RetentionPolicy.RUNTIME) //设置注解保存阶段为RUNTIME
public @interface MyAnno {
int age(); //定义age变量,属性为int类型
String[] addr(); //定义addr变量,属性为String一维数组类型
String name() default "zs"; //定义name变量,默认值为“zs”
}
以上便是配置注解的步骤。
(四)反射注解
在方法、属性、类等等的字节码文件上有以下三个方法。通过以下三个方法,可以指定利用注解,执行工作。
判断指定注解是否存在该元素上。
isAnnotationPresent(Class<? extends Annotation> annotationClass)
根据指定注解的Class字节码文件,获取注解信息。
getAnnotation(Class<A> annotationClass)
返回此元素上存在的所有注解。
getAnnotations()
案例:
import java.util.Arrays;
@MyAnno(age=18,addr= {"北京","上海"},value="程序猿")
public class AnnoTest{
public static void main(String args[]) {
Class<AnnoTest> clz = AnnoTest.class;
//isAnnotationPresent表示该MyAnno.class是否存在AnnoTest类上
boolean flag = clz.isAnnotationPresent(MyAnno.class);
if(flag) {
//getAnnotation获取指定注解
MyAnno myAnno = clz.getAnnotation(MyAnno.class);
//获取注解中的属性
String name = myAnno.name();
String[] addr = myAnno.addr();
int age = myAnno.age();
String value = myAnno.value();
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
System.out.println("地址:"+Arrays.toString(addr));
System.out.println("职业:"+value);
}else {
System.out.println("..........");
throw new RuntimeException("您没有指定注解");
}
}
}