Annotation概念及作用
概念
能够添加到 Java 源代码的语法元数据。类、方法、变量、参数、包都可以被注解,可用来将信息元数据与程序元素进行关联。Annotation 中文常译为“注解”。
作用
- 标记,用于告诉编译器一些信息
- 编译时动态处理,如动态生成代码
- 运行时动态处理,如得到注解信息
这里的三个作用实际对应着@Retention三种值分别表示的 Annotation
jdk自带的常用注解
@Overwrite:限定重写父类方法,该你注解只能运用于方法
@Deprecated:用于表示某个程序元素(类,方法等)已过时
@SuppressWarnings:抑制编译器警告
自定义注解
@interface来声明一个注解
自定义注解的过程就像在定义一个接口一样,注解中是可以增加属性,为一个注解增加属性就像在为一个接口定义方法
注解的属性需要在使用注解是进行赋值,赋值的方式(属性名=属性值,属性名=属性值)
-
使用default关键字可以在定义注解时给属性赋予一个默认值如果注解中只有一个属性需要被复制,并且这个属性的名字叫做value,则在赋值时可以省去value=
int version() default 1;
注解的属性必须是 基本数据类型 String Class 枚举 其他注解 以上数据类型的一维数组
元注解修饰注解
所谓的元注解是sun公司定义的用来修饰注解声明的注解:
@Retention
只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留的域, @Retention 包含一个 RetentionPolicy 类型的成员变量, 通过这个变量指定域。
- RetentionPolicy.SOURCE(源码时): 编译器直接丢弃这种策略的注解,注解不会存在.class文件中
- RetentionPolicy.CLASS(编译时): 编译器将把注解记录在 class 文件中. 当运行 Java 程序时, JVM 不会保留注解,也就是不会再内存中存在 . 说明是类加载器加载了注解这是默认值。
- RetentionPolicy.RUNTIME(运行时):编译器将把注解记录在 class 文件中. 当运行 Java 程序时, JVM 会保留注解. 程序可以通过反射获取该注解,Runtime是表示注解是在内存中存在的,所以可以用反射去得到该注解 被jvm运用。
代码如下:
@Retention(value=RetentionPolicy.RUNTIME)
public @Interface MyAnnotation{}
@Target
指定注解用于修饰类的哪个成员. @Target 包含了一个名为 value,类型为ElementType的成员变量。
@Documented
用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.
@Inherited
被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解,默认为false
自定义注解实例
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MethodInfo {
String author() default "trinea@gmail.com";
String date();
int version() default 1;
}
运行时的注解解析
利用反射技术,反射出 类 方法 成员变量 局部变量....位置上的注解,根据是否有注解和注解上属性的值来控制程序的运行
jdk中提供了AnnotatedElement接口,提供了反射注解的方法而Class, Constructor, Field, Method, Package 都实现过这个接口,所以这些类具有这个接口中定义的方法:
//获取该Target的某个注解,因为一个Target可以被多个Annotation修饰,Target可以是类、方法、变量、参数、包
<T extends Annotation> T getAnnotation(Class<T> annotationClass)
//获取所有注解组成的集合
Annotation[] getAnnotations()
//判断是否有注解
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
反射注解后,可以获取注解上的属性,获取属性的过程就像在调用方法一样
注意:只有保留在RUNTIME域的注解才能反射