zoukankan      html  css  js  c++  java
  • Java注解

    注解理解

          注释是为了向以后阅读这份代码的人解释说明一些事情,注解是注释的升级版,它可以向编译器、虚拟机等解释说明一些事情。

          注解是描述Java代码的代码,它能够被编译器解析,注解处理工具在运行时也能够解析注解。

         注解比java注释和Javadoc要强大得多,它们三者之间的重大的区别在于,Java注释和Javadoc描述所发挥的作用仅仅到编译时就止步了,而注解直到运行时都能够发挥作用。

         注解为我们提供了为类/方法/属性/变量添加描述信息的更通用的方式,而这些描述信息对于开发者、自动化工具、Java编译器和Java运行时来说都是有意义的,也就是说他们都能“读懂”注解信息。
         除了传递信息,我们也可以使用注解生成代码。我们可以使用注解,然后让注解解析工具来解析它们,以此来生成一些”模板化“的代码。

     

    注解的分类

    根据注解参数的个数,我们可以将注解分为三类:
        1.标记注解:一个没有成员定义的Annotation类型被称为标记注解。这种Annotation类型仅使用自身的存在与否来为我们提供信息。比如后面的系统注解@Override;
        2.单值注解
        3.完整注解  

      根据注解使用方法和用途,我们可以将Annotation分为三类:
        1.JDK内置系统注解
        2.元注解
        3.自定义注解

      

    元注解

         元注解即用来描述注解的注解

        

    Docemented

          当一个注解类型被@Documented元注解所描述时,那么无论在哪里使用这个注解,都会被Javadoc工具文档化。我们来看一下它的定义:

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Documented {
    }

    定义注解使用@interface关键字
    这个元注解被@Documented修饰,表示它本身也会被文档化。 @Retention元注解的值RetentionPolicy.RUNTIME表示@Documented这个注解能保留到运行时;@Target元注解的值ElementType.ANNOTATION_TYPE表示@Documented这个注解只能够用来描述注解类型。 

    Inherited

      表明被修饰的注解类型是自动继承的。具体解释如下:若一个注解类型被Inherited元注解所修饰,则当用户在一个类声明中查询该注解类型时,若发现这个类声明中不包含这个注解类型,则会自动在这个类的父类中查询相应的注解类型,这个过程会被重复,直到该注解类型被找到或是查找完了Object类还未找到。这个元注解的定义如下:

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
        public @interface Inherited {
    }

    这个元注解类型被@Documented所注解,能够保留到运行时,只能用来描述注解类型。

    Retention

      它表示一个注解类型会被保留到什么时候,比如以下代码表示Developer注解会被保留到运行时:

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Retention {
        /**
         * Returns the retention policy.
         * @return the retention policy
         */
        RetentionPolicy value();
    }

    我们在使用@Retention时,后面括号里的内容即表示他的取值,从以上定义我们可以看到,取值的类型为RetentionPolicy,这是一个枚举类型,它可以取以下值:
    * SOURCE:表示在编译时这个注解会被移除,不会包含在编译后产生的class文件中;
    * CLASS:表示这个注解会被包含在class文件中,但在运行时会被移除;
    * RUNTIME:表示这个注解会被保留到运行时,在运行时可以JVM访问到,我们可以在运行时通过反射解析这个注解。

    Target

      这个元注解说明了被修饰的注解的应用范围,也就是被修饰的注解可以用来注解哪些程序元素,它的定义如下:

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Target {
        /**
         * Returns an array of the kinds of elements an annotation type
         * can be applied to.
         * @return an array of the kinds of elements an annotation type
         * can be applied to
         */
        ElementType[] value();
    }

    看到它也会保留到运行时,而且它的取值是为ElementType[]类型(一个数组,意思是可以指定多个值),ElementType是一个枚举类型,它可以取以下值:

    • TYPE:表示可以用来注解类、接口、注解类型或枚举类型;
    • PACKAGE:可以用来注解包;
    • PARAMETER:可以用来注解参数;
    • ANNOTATION_TYPE:可以用来注解 注解类型;
    • METHOD:可以用来注解方法;
    • FIELD:可以用来注解属性(包括枚举常量);
    • CONSTRUCTOR:可以用来注解构造器;
    • LOCAL_VARIABLE:可用来注解局部变量。

    自定义注解

           自定义的注解需要解析工具来解析。注解的定义接近接口形式。

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Documented
    public @interface AliasFor {
    
        /**
         * Alias for {@link #attribute}.
         * <p>Intended to be used instead of {@link #attribute} when {@link #annotation}
         * is not declared &mdash; for example: {@code @AliasFor("value")} instead of
         * {@code @AliasFor(attribute = "value")}.
         */
        @AliasFor("attribute")
        String value() default "";
    
        /**
         * The name of the attribute that <em>this</em> attribute is an alias for.
         * @see #value
         */
        @AliasFor("value")
        String attribute() default "";
    
        /**
         * The type of annotation in which the aliased {@link #attribute} is declared.
         * <p>Defaults to {@link Annotation}, implying that the aliased attribute is
         * declared in the same annotation as <em>this</em> attribute.
         */
        Class<? extends Annotation> annotation() default Annotation.class;
    
    }

    在定义注释时的注意事项:

           注解类型是通过 @interface关键字定义的

           在”注解体“中,所有的方法均没有方法体且只允许public和abstract这两种修饰符号(不加修饰符缺省为public),注解方法不允许有throws子句;

           注解方法的返回值只能为以下几种:原始数据类型), String, Class, 枚举类型, 注解和它们的一维数组,可以为方法指定默认返回值。

           注解之中只能声明方法,不能声明字段。

    使用注解:

           给注解传值,给指定的注解方法传值需要指定注解方法名。

    通过反射来提取注解:

           java.lang.reflect.AnnotatedElement 注解元素

                已知实现类:

                        Class, Method, Filed, Constructor, Package

          可以提供此接口实现类注解的完美提取。

  • 相关阅读:
    u-boot 用哪个lds链接脚本
    u-boot-2019.07 移植步骤
    u-boot-2016.09 make编译过程分析(二)
    grep 命令搜索 带空格的字符
    uboot if_changed函数
    2019保险规划 待完善
    MongoDB Capped集合
    并发编程——详解 AQS CLH 锁
    Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
    观察者模式
  • 原文地址:https://www.cnblogs.com/hengwu/p/9716881.html
Copyright © 2011-2022 走看看