注解
我们从三个方面展开
- 1、元注解
- 2、自定义注解
- 3、注解解析,基本使用
一、元注解
通俗解释,这四个元注解:Retention、Target、Documented、Inherited。就是用来修饰自定义注解的注解。
(1)@Retention 注解的保留策略(生命周期)
周期值 | 说明 |
---|---|
@Retention(RetentionPolicy.SOURCE) | 注解仅存在于源码中,在class字节码文件中不包含 |
@Retention(RetentionPolicy.CLASS) | 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得 |
@Retention(RetentionPolicy.RUNTIME) | 注解会在class字节码文件中存在,在运行时可以通过反射获取到 |
(2)@Target 注解的作用目标
目标值 | 说明 |
---|---|
@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) | 包 |
(3)@Documented
注解可包含在javadoc中
(4)@Inherited
注解可以被继承
二、自定义注解
(1)定义自定义注解
@Retention(RetentionPolicy.RUNTIME)//设置运行时可获取的生命周期
@Inherited//设置可继承
@Documented//设置可用于javadoc
@Target({ElementType.FIELD})//设置可在成员变量上使用该注解
public @interface Init {
//定义注解方法
public String set() default "";
}
(2)使用自定义注解
public class UserVo {
@Init(set = "注解注入姓名")
private String name;
public String getName() {
return name == null ? "" : name;
}
}
(3)自定义注解的解析器
static class TestVoFactory {
public static UserVo create() {
UserVo userVo = new UserVo();
//获取所有属性值,包含private修饰的
Field[] fields = userVo.getClass().getDeclaredFields();
try {
for (Field field : fields) {
//1、获取该成员是否被 @Init 注解修饰
if (field.isAnnotationPresent(Init.class)){
//2、获取该字段的注解
Init init = field.getAnnotation(Init.class);
//设置private属性可通过反射方式赋值
field.setAccessible(true);
//3、给字段设置注解里的值
field.set(userVo,init.set());
}
}
}catch (Exception e){
e.printStackTrace();
return null;
}
return userVo;
}
}
(4)测试类
public static void main(String[] args) {
UserVo userVo = TestVoFactory.create();
System.out.println("======== "+userVo.getName());
}