zoukankan      html  css  js  c++  java
  • Android的注解(Annotation)学习之路

    目录

    一、什么是注解

    注解(Annotation)就是一个元数据,即描述数据的数据【是不是感觉和注释差不多,两者的区别看这里:注解和注释的区别

    二、为什么学习注解

    • 官方术语:如果你想把某个方法声明为服务,那么使用注解(Annotation)会更好一些,因为这种情况下需要注解和方法紧密耦合起来,开发人员也必须意识到这一点。
    • 自我理解:更好的优化理解代码
    • 自我表现:对菜鸟装一手
    • 自我现实:
      • 参考的代码出错了,都不知道哪里错,那么你就可以凉凉了
      • 面试一问三不知道,恭喜你凉凉了

    三、注解的基本作用

    • 编译检查
    • 在反射中使用注解(Annotation)
    • 根据注解(Annotation)生成帮助文档
    • 注解处理器
    • 在框架中的作用

    四、常用的注解类和元注解

    注解类:用于注解的一个类,如@Override

    元注解(meta-annotation):自定义注解上还有注解,共四个:@Target、@Retention、@Documented、@Inherited

    • @Override
    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    }

    代码片段01——调用@Override代码地方

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }

    代码片段02——@Override代码内容

    从代码片段01,我们可以知道注解@Override绝对是我们学习Android的人员最常用的注解了。那么它具体是什么作用呢?在代码片段02中,我们可以理解发现里面可以说是什么都没写,它的具体作用是只能是注解的基本作用之一,检测编译;具体体现是验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。比如上面的举例onCreate,如果没有@Override,且你的oncreate改为全部小写依旧可以编译通过,这时候编译器默认你创建了新的方法。

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

    代码片段03——@Documented代码内容

    在代码片段03中,我们可以理解发现里面可以说是什么都没写,它的具体作用是只能是注解的基本作用之一,根据注解(Annotation)生成帮助文档;具体体现是简单的标记注解,标识是否将注解信息包含在java文档中.

    • @Retention
    
    
    /**
    * Indicates how long annotations with the annotated type are to
    * be retained. If no Retention annotation is present on
    * an annotation type declaration, the retention policy defaults to
    * {@code RetentionPolicy.CLASS}.
    *
    * <p>A Retention meta-annotation has effect only if the
    * meta-annotated type is used directly for annotation. It has no
    * effect if the meta-annotated type is used as a member type in
    * another annotation type.
    *
    * @author Joshua Bloch
    * @since 1.5
    * @jls 9.6.3.2 @Retention
    */

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

    代码片段04——@Retention代码内容

    在代码片段04中,我们可以看到@Retention是根据RetentionPolicy类中的相应的结果集设置注解的保留时间【即设置注解的生命周期何时结束】,默认设置是RetentionPolicy.CLASS。查看RetentionPolicy类中的相应的结果集。

    
    
    /**
    * Annotation retention policy. The constants of this enumerated type
    * describe the various policies for retaining annotations. They are used
    * in conjunction with the {@link Retention} meta-annotation type to specify
    * how long annotations are to be retained.
    *
    * @author Joshua Bloch
    * @since 1.5
    */

    public
    enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }

    代码片段05——RetentionPolicy类代码内容

    在代码片段05中可知,这个类是设置注解什么时候结束的常量,即控制注解的生命周期的常量。分别为SOURCE,CLASS,RUNTIME。

    • RetentionPolicy.SOURCE:有效期在源码阶段,在编译阶段丢弃,这些注解在编译结束后不会有任何意义,也不会写入字节码中。
    • RetentionPolicy.CLASS:有效期至字节码文件。在类加载的时候丢弃,注解默认使用这种方式。
    • RetentionPolicy.RUNTIME:始终有效,在运行时也会保留。因此可以使用反射读取该注解的信息,自定义注解通常使用这种方式。
    • @Target
    
    
    /**
    * Indicates the contexts in which an annotation type is applicable. The
    * declaration contexts and type contexts in which an annotation type may be
    * applicable are specified in JLS 9.6.4.1, and denoted in source code by enum
    * constants of {@link ElementType java.lang.annotation.ElementType}.
    *
    * <p>If an {@code @Target} meta-annotation is not present on an annotation type
    * {@code T} , then an annotation of type {@code T} may be written as a
    * modifier for any declaration except a type parameter declaration.
    *
    * <p>If an {@code @Target} meta-annotation is present, the compiler will enforce
    * the usage restrictions indicated by {@code ElementType}
    * enum constants, in line with JLS 9.7.4.
    *
    * <p>For example, this {@code @Target} meta-annotation indicates that the
    * declared type is itself a meta-annotation type. It can only be used on
    * annotation type declarations:
    * <pre>
    * &#064;Target(ElementType.ANNOTATION_TYPE)
    * public &#064;interface MetaAnnotationType {
    * ...
    * }
    * </pre>
    *
    * <p>This {@code @Target} meta-annotation indicates that the declared type is
    * intended solely for use as a member type in complex annotation type
    * declarations. It cannot be used to annotate anything directly:
    * <pre>
    * &#064;Target({})
    * public &#064;interface MemberType {
    * ...
    * }
    * </pre>
    *
    * <p>It is a compile-time error for a single {@code ElementType} constant to
    * appear more than once in an {@code @Target} annotation. For example, the
    * following {@code @Target} meta-annotation is illegal:
    * <pre>
    * &#064;Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
    * public &#064;interface Bogus {
    * ...
    * }
    * </pre>
    *
    * @since 1.5
    * @jls 9.6.4.1 @Target
    * @jls 9.7.4 Where Annotations May Appear
    */

    @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(); }

    代码片段06——@Target代码内容

    在代码片段06中,我们看到@Target是表示在什么地方使用该注解。默认情况下,则该注解可以放在任意地方。查看代码片段07,可以设置的参数。

    /**
     * The constants of this enumerated type provide a simple classification of the
     * syntactic locations where annotations may appear in a Java program. These
     * constants are used in {@link Target java.lang.annotation.Target}
     * meta-annotations to specify where it is legal to write annotations of a
     * given type.
     *
     * <p>The syntactic locations where annotations may appear are split into
     * <em>declaration contexts</em> , where annotations apply to declarations, and
     * <em>type contexts</em> , where annotations apply to types used in
     * declarations and expressions.
     *
     * <p>The constants {@link #ANNOTATION_TYPE} , {@link #CONSTRUCTOR} , {@link
     * #FIELD} , {@link #LOCAL_VARIABLE} , {@link #METHOD} , {@link #PACKAGE} ,
     * {@link #PARAMETER} , {@link #TYPE} , and {@link #TYPE_PARAMETER} correspond
     * to the declaration contexts in JLS 9.6.4.1.
     *
     * <p>For example, an annotation whose type is meta-annotated with
     * {@code @Target(ElementType.FIELD)} may only be written as a modifier for a
     * field declaration.
     *
     * <p>The constant {@link #TYPE_USE} corresponds to the 15 type contexts in JLS
     * 4.11, as well as to two declaration contexts: type declarations (including
     * annotation type declarations) and type parameter declarations.
     *
     * <p>For example, an annotation whose type is meta-annotated with
     * {@code @Target(ElementType.TYPE_USE)} may be written on the type of a field
     * (or within the type of the field, if it is a nested, parameterized, or array
     * type), and may also appear as a modifier for, say, a class declaration.
     *
     * <p>The {@code TYPE_USE} constant includes type declarations and type
     * parameter declarations as a convenience for designers of type checkers which
     * give semantics to annotation types. For example, if the annotation type
     * {@code NonNull} is meta-annotated with
     * {@code @Target(ElementType.TYPE_USE)}, then {@code @NonNull}
     * {@code class C {...}} could be treated by a type checker as indicating that
     * all variables of class {@code C} are non-null, while still allowing
     * variables of other classes to be non-null or not non-null based on whether
     * {@code @NonNull} appears at the variable's declaration.
     *
     * @author  Joshua Bloch
     * @since 1.5
     * @jls 9.6.4.1 @Target
     * @jls 4.1 The Kinds of Types and Values
     */
    public enum ElementType {
        /** Class, interface (including annotation type), or enum declaration */
        TYPE,
    
        /** Field declaration (includes enum constants) */
        FIELD,
    
        /** Method declaration */
        METHOD,
    
        /** Formal parameter declaration */
        PARAMETER,
    
        /** Constructor declaration */
        CONSTRUCTOR,
    
        /** Local variable declaration */
        LOCAL_VARIABLE,
    
        /** Annotation type declaration */
        ANNOTATION_TYPE,
    
        /** Package declaration */
        PACKAGE,
    
        /**
         * Type parameter declaration
         *
         * @since 1.8
         */
        TYPE_PARAMETER,
    
        /**
         * Use of a type
         *
         * @since 1.8
         */
        TYPE_USE
    }

    代码片段07——ElementType类t代码内容

    • ElementType.TYPE:用于描述类,接口(包括注解类型),Enum
    • ElementType.FIELD:用于描述实例变量(包括枚举的常量)
    • ElementType.METHOD:用于描述方法
    • ElementType.PARAMETER:用于描述参数
    • ElementType.CONSTRUCTOR:用于构造方法
    • ElementType.LOCAL_VARIABLE:用于描述局部变量
    • ElementType.ANNOTATION_TYPE :用于描述注解
    • ElementType.PACKAGE:用于描述包
    • ElementType.TYPE_PARAMETER:since 1.8 表示该注解能写在类型变量的声明语句中
    • ElementType.TYPE_USE:since 1.8 表示该注解能写在使用类型的任何语句中
    • @Inherited
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Inherited {
    }

    代码片段08——@Inherited代码内容 

    代码08片段表示该注解类型被自动继承,如果用户在当前类中查询这个元注解类型,但是当前类的声明中不包含这个元注解类型,那么将自动查询其父类,直至查到该注解或到达顶层类

    附录

    注解和注释的区别

    •  定义不同
      • 注解:元数据,它是一种描述数据的数据。所以,可以说注解就是源代码的元数据。
      • 注释:是对源代码说明的文字
    • 作用对象不同
      • 注解:是给编译器看的。
      • 注释:是给人看的。
    • 书写范围不同
      • 注解:遵守一定的书写规范,以@开头,与工具一起使用
      • 注释:可以在代码的任何地方书写
    • 运行范围不同
      • 注解:可以参与编译器的任何阶段,对数据有一定的操作作用
      • 注释:被编译器忽略,不参与编译

    巨人的肩膀

  • 相关阅读:
    springboot maven打包插件
    maven打包指定main入口插件
    团队开发环境一致性性要求
    springboot 在idea中实现热部署
    IDEA 2018.1可用License服务(持续更新)
    IDEA打jar包
    3月18号
    3月17号
    3月16号
    3月13号
  • 原文地址:https://www.cnblogs.com/hahayixiao/p/13772011.html
Copyright © 2011-2022 走看看