1、介绍
Java注解又称Java标注,是在 JDK5时引入的新特性,注解(也被称为元数据),与类、接口、枚举是在同一个层次。
注解本身不提供任何作用,也不包含任何业务逻辑。注解更像是一个标签,表面被标注的这个地方,将具有某种特定的逻辑(特定的逻辑需要其它代码实现)。
注解可以声明在包、类、成员变量、方法、局部变量、方法参数等前面。
2、注解作用
- 最常见的是生成文档,也是java最早提供的注解。
- 在编译时进行格式检查,如@Override放在方法前,如果这个方法并不是覆盖了超类方法,编译时就能检查出来并抛异常。
- 跟踪代码依赖性,实现替代配置文件功能,比较常见的是spring2.5开始的基于注解配置,作用就是减少配置。
- 在反射的Class、Method、Field等函数中,有许多于Annotation相关的接口,可以在反射中解析并使用 Annotation。
3、注解使用三步骤
步骤一:定义注解(类似于定义接口),包括名字、能用到哪些地方,有效期,是否可以被继承等。
步骤二:使用注解,将定义好的注解标注在允许使用的指定地方。
步骤三:读取注解,使用反射读取被标注的注解,添加业务逻辑。
步骤一、步骤二没有实际作用,起决定性作用的是步骤三。
4、元注解
注解可分类两类:元注解、使用元注解定义的注解(JDK已有注解(@Override、@Deprecated、@SuppressWarnings、@FunctionalInterface
)、第三方框架定义的注解、自定义的注解)。
什么是元注解:用于定义注解的注解,包括@Retention、@Target、@Inherited、@Documented、@Repeatable
,且只能用于修饰注解,比较特殊。
元注解 | 描述 |
---|---|
@Documented | 代表该注解会被javadoc工具提取成文档 |
@Retention | 代表该注解的有效期 RetentionPolicy.SOURCE:表示编译期,如@Override,只做编译时的提示,不会写入字节码中 RetentionPolicy.CLASS:表示类加载期,会保存在class文件中,但在运行class文件被丢弃,也是默认值 RetentionPolicy.RUNTIME:表示运行期,也是最常用的,可以在代码运行时进行反射执行相关的操作 |
@Target | 表示该注解可以标注在哪 ElementType.TYPE:接口、类、枚举、注解 ElementType.FIELD:字段、枚举的常量 ElementType.METHOD:方法 ElementType.PARAMETER:参数 ElementType.CONSTRUCTOR:构造函数 ElementType.LOCAL_VARIABLE:局部变量 ElementType.ANNOTATION_TYPE:注解 ElementType.PACKAGE:包 |
@Inherited | 代表该注解可以被子类继承 |
@Repeatable | 代表该注解可以在同一个地方标注多次 |
5、定义注解、使用、读取
定义注解的基本形式:使用@interface
写法定义注解。
注解修饰符(元注解)
public @interface 注解名字 {
注解属性
}
使用及读取注解
/**
* 1、定义注解
*/
@Target(value = {ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation{
//属性:注解属性名写法后面带个小括号,和类属性写法存在差异
String value() default "defaultVal";
}
/**
* 2、使用注解
* 当注解中仅含有一个value属性时,可以简写
* @MyAnnotation(value = "实际的值") 简写为 @MyAnnotation("实际的值")
*/
@MyAnnotation("注解实际的value值")
class Person{
}
public class Demo {
public static void main(String[] args) {
/**
* 3、读取注解
*/
Class<Person> personClass = Person.class;
//读取类上的注解
MyAnnotation annotation = personClass.getAnnotation(MyAnnotation.class);
String value = annotation.value();
System.out.println(value);//注解实际的value值
}
}
/**
* 反射读取注解的一些其它方法:
* Class public <A extends Annotation> A getAnnotation(Class<A> annotationClass);读取类上的注解
* Method public <T extends Annotation> T getAnnotation(Class<T> annotationClass);读取方法上的注解
* Field public <T extends Annotation> T getAnnotation(Class<T> annotationClass);读取变量上的注解
* Package public <A extends Annotation> A getAnnotation(Class<A> annotationClass);读取包上的注解
* Class|Method|Field|Package Annotation[] getAnnotations();获取类/方法/变量/包上的注解列表
*/