什么是注解
注解的定义:一种元数据形式,可以添加到Java代码中。因此从定义可以看出注解仅仅是在源码中添加的一些标记,即元数据,对代码的运行没有任何影响。那注解能用来干嘛呢?一种技术的出现肯定是有其存在意义。注解本身是表示元数据,但是java为注解提供了单独的注解处理器,因此我们可以通过注解处理器来实现一些有意义的功能,比如编译检查,如@Override,生成文档@Document当然不止这些简单的功能,Spring中利用注解实现了AOP,事务等功能。
注解分类
我按照使用方式,将注解分成三类,元注解(meta-annoation),系统注解,自定义注解。
下面先介绍元注解和系统注解。
元注解
用于注解其他注解的注解,这些注解的主要作用类似于class,Interface等关键字,帮助我们实现自定义注解。java提供了下面几种元注解。
@Retention
用来指定注解保留到什么时机,有以下三个可选。
- RetentionPolicy.SOURCE:仅在源码中显示,class文件中不存在
- RetentionPolicy.CLASS :class文件中存在,但是运行时不存在。如果没有指定,则为默认值。
- RetentionPolicy.RUNTIME:在运行时存在,可以通过反射获取。
@Target
用来指定注解用在什么元素上,有下面多个值可选,注意这里Target的值可以同时指定多个,但是每个值只能出现一次,否则会抛出异常。
- ElementType.TYPE :类、接口、注解或者枚举
- ElementType.FIELD:属性、枚举常量上
- ElementType.FIELD:方法
- ElementType.PARAMETER:方法参数上
- ElementType.PARAMETER:构造器上
- ElementType.LOCAL_VARIABLE:本地变量
- ElementType.ANNOTATION_TYPE:注解
- ElementType.PACKAGE:包
- ElementType.TYPE_PARAMETER:可以在任何类型的参数上使用,包括泛型
- ElementType.TYPE_USE:等于TYPE+TYPE_PARAMETER
@Documented
@Documented 所标注内容,可以出现在javadoc中。
@Inherited
@Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。
@Repeatable
表示注解可以在同一个元素上重复使用
系统注解
- @Deprecated – @Deprecated 所标注内容,不再被建议使用。
- @Override – @Override 只能标注方法,表示该方法覆盖父类中的方法。
- @SuppressWarnings – @SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。
SuppressWarnings 常用的关键字的表格
1 | deprecation -- 使用了不赞成使用的类或方法时的警告 |
自定义注解
上面我们已经知道了java提供的元注解和系统注解,下面就来介绍如何自定义注解,下面是一个简单注解的示例:
1 |
|
说明:上面的作用是定义一个Annotation,它的名字是MyAnnotation。并且定义了俩个元素,分别定义了来个属性,一个是不同的String类型,另一个是字符串数组类型。定义了MyAnnotation1之后,我们可以在代码中通过@MyAnnotation(value='annoation',intValue={1,2,3})
来使用它。
从上面可以看出,自定义注解和接口很相似,就是在接口前加@
符号即可。其他的就和接口的形式相同。不过定义注解的时候,一般都会要求加上@Target和@Retention来个注解,来表示注解保留的时机和注解使用的地点。
注意:定义Annotation时,@Retention
可有可无。若没有@Retention
,则默认是RetentionPolicy.CLASS
。
注解作用
编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查。例如,@SuppressWarnings, @Deprecated和@Override都具有编译检查作用。
根据Annotation生成帮助文档: 通过给Annotation注解加上@Documented标签,能使该Annotation标签出现在javadoc中。
在反射中使用Annotation: 通过代码里标识的注解对代码进行分析。跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。