学习注解的第一件事情,搞清楚什么是注解?
什么是注解?先来看一下什么是注释
注释:注释就是我们添加在程序的源代码之中为了方便自己和他人阅读代码而添加的用于解释说明的文本,在编译时会过滤掉注释的内容。
注解(Annotation)一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面用于关联信息和数据,用来对这些元素进行说明,注释。在程序编译或运行的时候通过解析器解析这些注解来获取相应的信息和数据,就去执行相应的动作。
通俗来讲—注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记。JVM可以利用java的反射机制来获悉你的类及各种元素上有无何种标记,针对不同的标记,就去做相应的事件。
注解有什么作用?
JAVA中最早使用注解来生成文档:javadoc 根据相应的 javadoc注解来生成程序的API文档(生成的文档是 HTML 格式),以下是常见的javadoc的注解:
@author 开发当前模块的作者
@version 当前模块的版本
@see 参考转向,也就是链接到相关主题
@param 对方法中某参数的说明
@return 对方法返回值的说明
@exception 对方法可能抛出的异常进行说明使用注解对代码进行格式检查:
- @Override 表示当前方法覆盖了父类的方法
- @Deprecation 表示方法已经过时,方法上有横线,使用时会有警告
- @SuppviseWarnings 表示关闭一些警告信息(通知java编译器忽略特定的编译警告)
- 跟踪代码之间的依赖性,替代各种配置文件的功能
注解的分类:
JDK自带注解:
- JAVA目前内置了三种标准注解:@Override、@Deprecated、@SuppressWarnings、以及四种元注解:@Target、@Retention、@Documented、@Inherited
- 自定义注解:自己写的注解
- 第三方注解:别人开发的注解,像各种流行框架里的注解,这些都是第三方注解
学习自己定义和使用注解
在写注解之前先看看注解的语法要求:
使用@interface关键字来定义注解,它会自动继承java.lang.annotation.Annotation接口,就像一个类会自动继承Object类一样。在定义注解时,不能继承其他的注解或接口。注解中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型。
为什么定义注解上方还有注解呢?
元注解:元注解的作用就是负责注解其他注解,JAVA 定义了4个元注解类型,用来提供对其他Annotation类型进行说明:
- @Target 注解的作用域,表示该注解可以用于一个类中的那些属性及方法上,如果作用域类型有多个用英文逗号分隔,可选的参数在枚举类ElementType 中:
**{构造器:CONSTRUCTOR}**
**{成员变量/域:FIELD}**
**{局部变量:LOCAL_VARIABLE}**
**{方法:METHOD}**
**{包:PACKAGE}**
**{参数:PARAMETER}**
**{类、接口(包括注解类型) 或ENUM:TYPE}**
- @Retention 注解的生命周期,表示在什么阶段保留该注解信息(源码、字节码、字节码文件对象),可选的参数在枚举类RetentionPolicy 中:
**{在源文件中有效:SOURCE}** 只在源文件中保留,而被编译器丢弃
**{在字节码文件中有效:CLASS}** 保留在字节码文件中,被JVM忽略
**{在运行时有效:RUNTIME}** 加载成对象时还存在,JVM加载时被读取
- @Documented 表示用Javadoc生成文档的时候会包含注解
- @Inherited 标识性元注解,表示用这个定义的注解注解一个类(只能是类、其他无效)的时候让该类的子类也继承该注解
解析注解:通过反射获取类、函数或成员上运行时注解信息,从而实现动态控制程序运行的逻辑。
先写一个自定义的注解:
再利用反射获取获取到元素上的注解
- isAnnotationPresent:判断是否标注了指定注解
- getAnnotation:获取指定注解,没有则返回null
- getAnnotations:获取所有注解,包括继承自基类的,没有则返回长度为0的数组
- getDeclaredAnnotations:获取自身显式标明的所有注解,没有则返回长度为0的数组
Tips:
ElementType.LOCAL_VARIABLE是方法中的本地变量。但是目前的javac不会在bytecode中的local
variable中保存annotation信息,所以就无法在runtime时获取该annotaion。也就是说ElementType.LOCAL_VARIABLE只能用在RetentionPolicy.SOURCE情况下