Java注解——这些@圈圈都是个啥?

1、啥是@ 注解

  首先看名字,注解——跟注释长得挺像。注解跟注释很相似,类比思考一下,注释是干什么用的?html

  /**java

  * 注释是一种存在于源代码中的信息,用于开发过程当中给程序员提示和帮助。程序员

  **/web

  注解也是相似的东西,他也带来信息,不过跟注释不同的地方在于,注解能够保留到编译以后的二进制代码中,而注释则在编译阶段就被抛弃了。spring

  因为注解拥有能够保留到二进制代码中的特征,所以能够经过注解为框架带来元信息。api

  举个例子:最经常使用的注解之一@Controller 将这个注解标注到Controller类上,在springMVC(一种java mvc框架)构建ApplicationContext环境的时候,就会发现,哦这是一个控制器,这个控制器要映射到url上。这就至关于在类上面添加了一个能保留到二进制代码中的//这是一个控制器类 这么一段注释。数组

 

2、注解的语法

定义注解时,须要一些元注解(meta-annotation),如@Target和@Retentionmvc

 

  • @Target用来定义注解将应用于什么地方(如一个方法或者一个域)框架

  • @Retention用来定义注解在哪个级别可用,在源代码中(source),类文件中(class)或者运行时(runtime)url

  • 在注解中,通常都会包含一些元素以表示某些值。当分析处理注解时,程序能够利用这些值。没有元素的注解称为标记注解(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 "";

 

}

 

3、注解的使用

说过了注解是什么东西,注解怎么定义,该说说注解如何使用了。

首先声明一点,注解都是给框架用的,说到框架使用,很容易联想到反射。

 

<A extends Annotation
A
getAnnotation(Class<A> annotationClass) 
          若是存在该元素的指定类型的注释,则返回这些注释,不然返回 null。
 Annotation[] getAnnotations() 
          返回此元素上存在的全部注释。

 Filed类等能够拥有注解的反射类型都有相似能够获取注解的方法

<T extends Annotation
T
getAnnotation(Class<T> annotationClass) 
          若是存在该元素的指定类型的注释,则返回这些注释,不然返回 null。

 

4、总结

注解在java中属于一种比较高级并且麻烦的技术,非框架编写者基本不会用到这种技术。可是了解注解是个什么东西很重要,由于注解在框架的快捷配置中起了决定性的做用,也让no xml党们拥有了一个脱离xml配置的机会。了解注解可让咱们不止知其然还知其因此然,在使用框架的时候不至于迷迷糊糊的就@了个圈在上面。

相关文章
相关标签/搜索