注解概述
- Annotation 其实就是
代码里的特殊标记
, 这些标记可以在编译, 类加
载, 运行时被读取, 并执行相应的处理。通过使用Annotation, 程序员
可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。代
码分析工具、开发工具和部署工具可以通过这些补充信息进行验证
或者进行部署 - Annotation 可以像修饰符一样被使用, 可用于 修饰包, 类, 构造器, 方法, 成员变量, 参数, 局部变量的声明, 这些信息被保存在 Annotation
的 “name=value” 对中
自定义注解
- 定义新的 Annotation 类型使用 @interface 关键字,自定义注解自动继承了java.lang.annotation.Annotation
- Annotation 的成员变量:
- 以
无参数方法的形式来声明
。其方法名和返回值定义了该成员的名字和类型
,我们称为配置参数. - 类型只能是
八种基本数据类型、String 类型 、Class 类型 、enum 类型 、Annotation 类型 、以上所有类型的数组
- 可以在定义 Annotation 的成员变量时为其指定初始值, 指定成员变量的初始值可使用 default 关键字
- 如果只有一个参数成员,建议使用
参数名为value
- 以
- 如果定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值。格式是“参数名 = 参数值”,如果只有一个参数成员,且名称为value,可以省略“value=”
代码示例
注解定义:
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
// 定义注解的成员变量,以无参的方法形式声明,方法名和返回值定义了该成员的名字和类型
// 并给该成员变量指定默认值
String value() default "hello";
}
注解的使用:
//@MyAnnotation
//@MyAnnotation("hello2")
@MyAnnotation(value = "hello2")
public class AnnotationTest {
}
注意:注解要有实际意义的话,要看我们的实际业务场景,我们可以通过反射的方式获取注解,并进行该注解的实际业务处理
通过反射获取注解信息:
public class AnnotationTest02 {
public static void main(String[] args) {
Class<AnnotationTest> myAnnotationClass = AnnotationTest.class;
Annotation[] annotations = myAnnotationClass.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println("通过反射获取MyAnnotation类上的注解:" + annotation);
}
}
}
运行结果:
通过反射获取MyAnnotation类上的注解:@com.javastudy.annotation.MyAnnotation(value=hello2)
四种元注解
- JDK 的
元注解是用于修饰 注解的
。 - JDK5.0提供了4个标准的meta-annotation类型,分别是:
Retention
:表示注解的生命周期,在哪个阶段有效Target
:表示注解用于饰哪些程序元素(如:类,方法,属性)Documented
:注解 javadoc 工具提取成文档Inherited
:注解可以被继承,子类也拥有了注解
@Retention
- @Retention只能用于修饰一个 Annotation 定义(即用于修饰定义的注解), 用于指定该 Annotation 的生命周期
- @Rentention 包含一个 RetentionPolicy 类型的成员变量, 使用
@Rentention 时必须为该 value 成员变量指定值
RetentionPolicy.SOURCE
:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释RetentionPolicy.CLASS
:在class文件中有效(即class保留) , 当运行 Java 程序时, JVM不会保留注解。 这是默认值RetentionPolicy.RUNTIME
:在运行时有效(即运行时保留),当 当行 运行 Java 程序时, JVM 会 会保留注释。程序 可以通过反射获取 该注释
代码示例:
@Retention(value = RetentionPolicy.RUNTIME)
:表示在代码运行时该注解有效
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "hello";
}
@Target
- @Target用于指定被修饰的 Annotation 能用于修饰哪些程序元素
- @Target 也包含一个名为 value 的成员变量,value可以有以下取值:
代码示例:
@Target({ElementType.TYPE,ElementType.METHOD})
:表示 MyAnnotation 这个注解可以修饰类,接口,和方法
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "hello";
}
@Documented
- 用于指定被该元注解 修饰的 Annotation 类将被 javadoc 工具提取成文档。默认情况下,javadoc是不包括注解的
- 定义为Documented的注解必须设置Retention值为RUNTIME
@Inherited
- 被它修饰的 Annotation 将具有 继承性。如果某个类使用了被@Inherited 修饰的 Annotation, 则其子类将自动具有该注解
- 比如:如果把标有@Inherited注解的自定义的注解标注在类级别上,子类则可以继承父类类级别的注解
- 实际应用中,使用较少