注解
概述
对java中类、方法、成员变量做标记,然后进行特殊处理
例如 junit中 @Test 标记的方法就可以被当作测试方法执行
自定义注解
1
2
3
public @interface 注解名称 {
public 属性类型 属性名() [default 默认值];
}
可以不标记 public 默认就是public
这里的属性名有一个特殊属性名,
value
当只有一个属性为value时,注解时可以不写属性名value,但如果有多个属性名,且没有默认值时,需要写明value这个属性名
Java自定义注解开发_小滦不秃头♂️的博客-CSDN博客_java 自定义注解
基本注解
@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接口,都拥有解析注解的能力
流程
-
先获取指定的对象 比如类对象 方法对象
-
判断该对象上是否存在指定的注解
-
如果存在 直接获取注解对象
-
再对该对象进行操作
举例
这里以类对象和方法对象的注解进行示例
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());
}
}
}
这里用到了 反射 这一技术