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片段表示該注解類型被自動繼承,如果用戶在當前類中查詢這個元注解類型,但是當前類的聲明中不包含這個元注解類型,那么將自動查詢其父類,直至查到該注解或到達頂層類

附錄

注解和注釋的區別

  •  定義不同
    • 注解:元數據,它是一種描述數據的數據。所以,可以說注解就是源代碼的元數據。
    • 注釋:是對源代碼說明的文字
  • 作用對象不同
    • 注解:是給編譯器看的。
    • 注釋:是給人看的。
  • 書寫范圍不同
    • 注解:遵守一定的書寫規范,以@開頭,與工具一起使用
    • 注釋:可以在代碼的任何地方書寫
  • 運行范圍不同
    • 注解:可以參與編譯器的任何階段,對數據有一定的操作作用
    • 注釋:被編譯器忽略,不參與編譯

巨人的肩膀


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM