前言
基于愈来愈流行的框架都是基于注解开发的,我们使用的时候也越发方便,在平时的开发中我们也通过自定义注解来使很多功能通用和简单,便于开发功能。
那么我们在开发自定义注解的时候,就必须要依赖于@Target、@Retention、@Documented、@Inherited这四个元注解,所以接下来就了解一下这几个元注解。
元注解就是在我们声明自定义注解的时候需要用到的注解,它们是注解的亚当和夏娃。
1 @Target
@Target 说明了它所能修饰的对象范围,可修饰在 类、接口、枚举、注解、类成员等上面,也就是 ElementType 的值,具体如下:
注解 | 修饰范围 |
---|---|
TYPE | 类、接口(包括Annotation类型)、枚举 |
FIELD | 字段(包括枚举) |
METHOD | 方法 |
PARAMETER | 方法参数 |
CONSTRUCTOR | 构造函数 |
LOCAL_VARIABLE | 局部变量 |
ANNOTATION_TYPE | 注解 |
PACKAGE | 包 |
TYPE_PARAMETER | 类型参数(Since 1.8) |
TYPE_USE | 标注在任何类型名称(Since 1.8) |
2 @Retention
当注解标注的类编译以什么方式保留,具体值如下:
注解 | 编译方式 |
---|---|
SOURCE | 编译时忽略 |
CLASS | 保留在类文件中 |
RUNTIME | 保留至运行时 |
3 @Documented
此注解就比较简单了,是否生成 javadoc 文档。
4 @Inherited
指示此注释类型是否会被继承,是一个标记性注解。当父类的注解中用@Inherited修饰的时候,我们才可以通过反射 getAnnotations() 方法获取到子类的注解,反之,如果父类的注解中没有用@Inherited修饰时,子类获取不到父类的注解。
4.1 示例
由于这个注解比较难理解,举例子说明。
- 创建注解 @AnnoA, @Inherited 修饰
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface AnnoA {
}
- 创建注解 @AnnoB, 没 @Inherited修饰
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnoB {
}
- 创建父类 (People.class)
父类我们先用 @AnnoA 修饰。
@AnnoA
public class People {
}
- 创建子类 (Student.class)
public class Student extends People{
}
- 测试(获取 @AnnoA注解)
public class AnnoTest {
public static void main(String[] args) {
System.out.println("获取注解");
System.out.println(" Prople 类");
Class<People> peopleClass = People.class;
Annotation[] annotations1 = peopleClass.getAnnotations();
for (Annotation annotation : annotations1) {
System.out.println(annotation.toString());
}
System.out.println(" Student 类");
Class<Student> studentClass = Student.class;
Annotation[] annotations = studentClass.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation.toString());
}
}
}
测试结果:
可以看到,通过子类(Student.class)也可以获取到 @AnnoA 注解。
- 测试(获取 @AnnoB 注解)
首先修改父类(People.class)为 @AnnoB 注解
@AnnoB
public class People {
}
从测试结果可以看出,我们是获取不到子类(Student.class)的注解。
尽管网上还有一大堆关于元注解的博客和资料,但自己没总结总归是记不住,所以自己总结以便自己查阅和来访者学习(若君愿阅)。