一、啥是@ 注解
首先看名字,注解——跟注释长得挺像。注解跟注释很类似,类比思考一下,注释是干什么用的?
/**
* 注释是一种存在于源代码中的信息,用于开发过程中给程序员提示和帮助。
**/
注解也是类似的东西,他也带来信息,不过跟注释不一样的地方在于,注解可以保留到编译之后的二进制代码中,而注释则在编译阶段就被抛弃了。
由于注解拥有可以保留到二进制代码中的特征,因此可以通过注解为框架带来元信息。
举个例子:最常用的注解之一@Controller 将这个注解标注到Controller类上,在springMVC(一种java mvc框架)构建ApplicationContext环境的时候,就会发现,哦这是一个控制器,这个控制器要映射到url上。这就相当于在类上面添加了一个能保留到二进制代码中的//这是一个控制器类 这么一段注释。
二、注解的语法
定义注解时,需要一些元注解(meta-annotation),如@Target和@Retention
@Target用来定义注解将应用于什么地方(如一个方法或者一个域)
@Retention用来定义注解在哪一个级别可用,在源代码中(source),类文件中(class)或者运行时(runtime)
在注解中,一般都会包含一些元素以表示某些值。当分析处理注解时,程序可以利用这些值。没有元素的注解称为标记注解(marker annotation)
四种元注解,元注解专职负责注解其他的注解,所以这四种注解的Target值都是ElementType.ANNOTATION_TYPE
注解说明
@Target
表示该注解可以用在什么地方,由ElementType枚举定义
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明
ANNOTATION_TYPE:注解声明(应用于另一个注解上)
TYPE_PARAMETER:类型参数声明(1.8新加入)
TYPE_USE:类型使用声明(1.8新加入)
PS:当注解未指定Target值时,此注解可以使用任何元素之上,就是上面的类型
@Retention
表示需要在什么级别保存该注解信息,由RetentionPolicy枚举定义
SOURCE:注解将被编译器丢弃(该类型的注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里)
CLASS:注解在class文件中可用,但会被VM丢弃(该类型的注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机(JVM)中)
RUNTIME:VM将在运行期也保留注解信息,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息)
PS:当注解未定义Retention值时,默认值是CLASS
@Documented
表示注解会被包含在javaapi文档中
@Inherited
允许子类继承父类的注解
注解元素
注解元素可用的类型如下:
所有基本类型(int,float,boolean,byte,double,char,long,short)
String
Class
enum
Annotation
以上类型的数组 如果使用了其他类型,那编译器就会报错。也不允许使用任何包装类型。注解也可以作为元素的类型,也就是注解可以嵌套。 元素的修饰符,只能用public或default。
默认值限制
编译器对元素的默认值有些过分挑剔。首先,元素不能有不确定的值。也就是说,元素必须要么具有默认值,要么在使用注解时提供元素的值。
其次,对于非基本类型的元素,无论是在源代码中声明,还是在注解接口中定义默认值,都不能以null作为值。这就是限制,这就造成处理器很难表现一个元素的存在或缺失状态,因为每个注解的声明中,所有的元素都存在,并且都具有相应的值。为了绕开这个限制,只能定义一些特殊的值,例如空字符串或负数,表示某个元素不存在。
@Target(ElementType.Method)
@Retention(RetentionPolicy.RUNTIME)
public @interface MockNull {
public int id() default -1;
public String description() default "";
}
三、注解的使用
说过了注解是什么东西,注解怎么定义,该说说注解如何使用了。
首先声明一点,注解都是给框架用的,说到框架使用,很容易联想到反射。
A
Class annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
Filed类等可以拥有注解的反射类型都有类似可以获取注解的方法
T
Class annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
四、总结
注解在java中属于一种比较高级而且麻烦的技术,非框架编写者基本不会用到这种技术。但是了解注解是个什么东西很重要,因为注解在框架的快捷配置中起了决定性的作用,也让no xml党们拥有了一个脱离xml配置的机会。了解注解可以让我们不止知其然还知其所以然,在使用框架的时候不至于迷迷糊糊的就@了个圈在上面。