0%

注解基本介绍

什么是注解

注解的定义:一种元数据形式,可以添加到Java代码中。因此从定义可以看出注解仅仅是在源码中添加的一些标记,即元数据,对代码的运行没有任何影响。那注解能用来干嘛呢?一种技术的出现肯定是有其存在意义。注解本身是表示元数据,但是java为注解提供了单独的注解处理器,因此我们可以通过注解处理器来实现一些有意义的功能,比如编译检查,如@Override,生成文档@Document当然不止这些简单的功能,Spring中利用注解实现了AOP,事务等功能。

注解分类

我按照使用方式,将注解分成三类,元注解(meta-annoation),系统注解,自定义注解。
下面先介绍元注解和系统注解。

元注解

用于注解其他注解的注解,这些注解的主要作用类似于class,Interface等关键字,帮助我们实现自定义注解。java提供了下面几种元注解。

@Retention

用来指定注解保留到什么时机,有以下三个可选。

  1. RetentionPolicy.SOURCE:仅在源码中显示,class文件中不存在
  2. RetentionPolicy.CLASS :class文件中存在,但是运行时不存在。如果没有指定,则为默认值。
  3. RetentionPolicy.RUNTIME:在运行时存在,可以通过反射获取。

@Target

用来指定注解用在什么元素上,有下面多个值可选,注意这里Target的值可以同时指定多个,但是每个值只能出现一次,否则会抛出异常。

  1. ElementType.TYPE :类、接口、注解或者枚举
  2. ElementType.FIELD:属性、枚举常量上
  3. ElementType.FIELD:方法
  4. ElementType.PARAMETER:方法参数上
  5. ElementType.PARAMETER:构造器上
  6. ElementType.LOCAL_VARIABLE:本地变量
  7. ElementType.ANNOTATION_TYPE:注解
  8. ElementType.PACKAGE:包
  9. ElementType.TYPE_PARAMETER:可以在任何类型的参数上使用,包括泛型
  10. ElementType.TYPE_USE:等于TYPE+TYPE_PARAMETER

@Documented

@Documented 所标注内容,可以出现在javadoc中。

@Inherited

@Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。

@Repeatable

表示注解可以在同一个元素上重复使用

系统注解

  1. @Deprecated – @Deprecated 所标注内容,不再被建议使用。
  2. @Override – @Override 只能标注方法,表示该方法覆盖父类中的方法。
  3. @SuppressWarnings – @SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。

SuppressWarnings 常用的关键字的表格

1
2
3
4
5
6
7
deprecation  -- 使用了不赞成使用的类或方法时的警告
unchecked -- 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。
fallthrough -- 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。
path -- 在类路径、源文件路径等中有不存在的路径时的警告。
serial -- 当在可序列化的类上缺少 serialVersionUID 定义时的警告。
finally -- 任何 finally 子句不能正常完成时的警告。
all -- 关于以上所有情况的警告。

自定义注解

上面我们已经知道了java提供的元注解和系统注解,下面就来介绍如何自定义注解,下面是一个简单注解的示例:

1
2
3
4
5
6
7
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();

int[] intValue();
}

说明:上面的作用是定义一个Annotation,它的名字是MyAnnotation。并且定义了俩个元素,分别定义了来个属性,一个是不同的String类型,另一个是字符串数组类型。定义了MyAnnotation1之后,我们可以在代码中通过@MyAnnotation(value='annoation',intValue={1,2,3})来使用它。

从上面可以看出,自定义注解和接口很相似,就是在接口前加@符号即可。其他的就和接口的形式相同。不过定义注解的时候,一般都会要求加上@Target和@Retention来个注解,来表示注解保留的时机和注解使用的地点。

注意:定义Annotation时,@Retention可有可无。若没有@Retention,则默认是RetentionPolicy.CLASS

注解作用

  1. 编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查。例如,@SuppressWarnings, @Deprecated和@Override都具有编译检查作用。

  2. 根据Annotation生成帮助文档: 通过给Annotation注解加上@Documented标签,能使该Annotation标签出现在javadoc中。

  3. 在反射中使用Annotation: 通过代码里标识的注解对代码进行分析。跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。