java注解
# JDK 中预定义的一些注解(针对编辑器)
@Override
: 检测被该注解标注的方法是否是继承自父类(接口)@Deprecated
: 该注解标注的内容,表示已过时@SuppressWarnings("all")
: 压制警告,需要传参,一般传all
压制所有警告
# 自定义注解
# 定义注解
public @interface 注解名称{}
1
注解本质上就是一个接口,改接口默认继承 Annotation 接口
public interface 注解名称 extends java.lang.annotation.Annotation{}
1
# 注解属性
接口中的抽象方法为注解中的属性 要求:
- 属性的返回值类型只能为以下几种
- 基本数据类型
- String
- 枚举
- 注解
- 以上类型数组
public @interface MyAnno{
int age();
String name() default "张三";
Person p1(); // Person是enum类
MyAnno2 anno(); // MyAnno2是一个自定义注解
}
1
2
3
4
5
6
2
3
4
5
6
- 定义了属性,在使用时需要给属性赋值
- 果果定义属性时,使用
default
关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值 - 如果只有一个属性需要赋值,并且属性的名称是
value
,则value
可以省略,直接定义值即可 - 数组赋值时,值使用大括号{}包裹,如果数组只有一个值,则{}可以省略
// anno
int age();
// use
@MyAnno(age=1)
// anno: default
String name() default "张三";
// use
@MyAnno() // 省略使用默认值
@MyAnno(name="李四")
// anno: value
String value();
// use
@MyAnno("李四") // 只有一个属性,且属性名为value可省略属性名称
@MyAnno(value="李四")
// anno: 枚举
Person per();
//use
@MyAnno(per=Person.p1)
// anno: 注解
MyAnno2 anno();
// use
@MyAnno(anno=@MyAnno2)
// anno: 数组
String[] strs;
// use
@MyAnno(strs={"张三","李四"}) // 数组中的值用大括号包裹
@MyAnno(strs="张三") // 数组中只有一个值可以省略大括号
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
32
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
32
# 元注解
用于描述注解的注解
@Target
: 描述注解能够作用的位置@Target(ElementType.TYPE)
: 表示该注解可以作用于类上@Target(ElementType.FIELD)
: 表示该注解可以作用于成员变量上@Target(ElementType.METHOD)
: 表示该注解可以作用于方法上
@Retention
: 描述注解被保留的阶段@Retention(RetentionPolicy.RUNTIME)
: 当前被描述的注解会保留到 class 字节码文件中,并被 JVM 读取到,一般自定义注解使用 RUNTIME
@Decumented
: 描述注解是否被抽取到 api 文档中@Inherited
: 描述注解是否被子类继承
# 解析注解
在程序中获取注解的值
// 使用
package cn.mrcdh.annotation;
import java.lang.reflect.Method;
/**
* 使用注解
*/
@CustomAnno(className = "cn.mrcdh.annotation.Student", methodName = "upSchool")
public class AnnoTest {
public static void main(String[] args) throws Exception {
// 获取注解定义的位置对象
// 因为注解定义在类上所以获取本类
Class<AnnoTest> aClass = AnnoTest.class;
// 获取指定的注解
CustomAnno anno = aClass.getAnnotation(CustomAnno.class);
// 调用注解中的抽象方法获取配置的属性值
String className = anno.className();
String methodName = anno.methodName();
// 获取类
Class cls = Class.forName(className);
// 创建对象
Object o = cls.newInstance();
// 获取方法对象
Method method = cls.getMethod(methodName);
// 执行方法
method.invoke(o);
}
}
// ------------------------------
// 注解类
package cn.mrcdh.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnno {
String className();
String methodName();
}
package cn.mrcdh.annotation;
public class Student {
public void upSchool(){
System.out.println("上学啦....");
}
}
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
上次更新: 2023/09/22, 16:54:32