zoukankan      html  css  js  c++  java
  • Java注解——这些@圈圈都是个啥?

    一、啥是@ 注解

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

      /**

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

      **/

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

      由于注解拥有可以保留到二进制代码中的特征,因此可以通过注解为框架带来元信息。

      举个例子:最常用的注解之一@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 extends Annotation
    A
    getAnnotation(Class<A> annotationClass) 
              如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
     Annotation[] getAnnotations() 
              返回此元素上存在的所有注释。

     Filed类等可以拥有注解的反射类型都有类似可以获取注解的方法

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

    四、总结

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

  • 相关阅读:
    delphi 焦点定位
    delphi cxgrid 添加分页
    推动力
    python enumerate 函数用法
    Python pass语句作用与用法
    Python 元组知识点
    python 练习多级菜单思路
    一点练习题
    优化mysql服务器
    对自己的忠告
  • 原文地址:https://www.cnblogs.com/wencheng256/p/5661644.html
Copyright © 2011-2022 走看看