java基础之Annotation
元注解
元注解由 java API 提供 , 用来定义注解的注解
@Document : 文档
被该注解注册的元素可以被javadoc提取 , 生成API文档
@Tartget : 目标
该注解的目标元素 , 元素类型在ElementType中定义
ElementType.CONSTRUCTOR : 构造方法
ElementType.FIELD : 字段
ElementType.LOCAL_VARIABLE : 局部变量
ElementType.METHOD : 方法
ElementType.PARAMETER : 参数
ElementType.TYPE : 类 , 接口 , 注解 , 枚举声明
@Inherited : 继承
允许子类继承父类的注解
@Retention : 保留
该注解被保留的级别 , 级别在RetentionPolicy中定义
RetentionPolicy.SOURCE : 注解在源码阶段被保留 , 在编译时被丢弃
RetentionPolicy.CLASS : 注解在编译阶段被保留 , 在JVM运行时被丢弃
RetentionPolicy.RUNTIME : 注解在运行时被保留 , 可以通过反射机制获取注解的信息
自定义注解
通过@interface声明 , 方法名就是参数的名称 , 返回值类型就是参数的类型
返回值类型 :
基本数据类型 , Class , String , enum , 注解及以上类型的数组
可以通过default来声明默认值
/**
*
* 定义注解类TestA
*/
@Target({ElementType.TYPE,
ElementType.METHOD,
ElementType.FIELD,
ElementType.CONSTRUCTOR,
ElementType.PARAMETER,
ElementType.LOCAL_VARIABLE}) //目标
@Retention(RetentionPolicy.RUNTIME) //保留
public @interface TestA {
//声明注解的属性字段:
//类型 字段名() [default 默认值];
int age() default 0;
Class type();
String name() default "";
//使用value,可以省略属性名
//即:@TestA("aaa"),只有value的使用
String value() default "";
//String[] value()defaule "";//一维数组
//String value()和String[] value()可以直接写@TestA("aaa")或@TestA({"aa","bb","cc"});
}
注解的使用
使用自定的注解
自定义注解 :
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE
, ElementType.CONSTRUCTOR
, ElementType.FIELD
, ElementType.LOCAL_VARIABLE
, ElementType.METHOD
, ElementType.PARAMETER})
public @interface Flag {
String flag() default "";
}
使用自定注解 :
@Flag(flag = "type")
public class Student {
@Flag(flag = "field")
public String name;
@Flag(flag = "constructor")
public Student() {
}
@Flag(flag = "method")
public void study(@Flag(flag = "parameter") String course) {
@Flag(flag = "local_variable")
int hour = 10;
System.out.println("study" + hour + "hour");
}
}
解析注解
此处的解析 , 是在运行时(Runtime)通过反射机制运行处理的注解
Class , Constructor , Field , Method , Package都是java.lang.reflect.AnnotatedElement的实现类 , 可以通过该接口的方法 , 获取被注册元素上注解
解析指定的注解时 , 注解的Retention , 需要是RetentionPolicy.RUNTIME
Class<?> aClass = Class.forName(className);
boolean present = aClass.isAnnotationPresent(Flag.class);
if (present) {
Flag flag = aClass.getAnnotation(Flag.class);
String flagData = flag.flag();
System.out.println("data:" + flagData); // type
}