HappyBKs教你寫Java註解(1)——註解的分類、運行機制、做用域及概念彙總

註解這東西,已經在咱們的編程生活中習覺得常了。覆蓋一個父類的方法,套用Spring、Mybatis中的編程套路,編寫JUnit測試函數等等。你會發現,做爲一個Java Coder,你無時無刻不在接觸它們。java

可是如何編寫一個屬於本身的註解,或是但願可以看懂那些NB框架的源代碼,都有必要讓你我去掌握編寫自定義註解的方法。spring

本系列開始,我將和博客的觀衆們一塊兒學習java註解的開發。編程


註解分類(按照來源來分)app

jdk中的註解:框架

@Override 重寫父類的方法。若是父類沒有該方法則編譯報錯ide

@Override
	public String toString() {
		return "Member [id=" + id + ", familyName=" + familyName
				+ ", givenName=" + givenName + ", salary=" + salary + "]";
	}

@Deprecated 之前的定義的類或方法,你們正用得high,你卻以爲好像這樣設計並很差,因而加入了新的類或方法來代替它們。可是,這樣作,之前的小夥伴們又要抱怨了,"你這個先後版本不兼容"云云,因此咱們須要用一個註解指明"存在但已過期,可用但不推薦」,這就是@Deprecated。函數

好比,因爲如今的貓都不捉老鼠了,因此,下面這個方法,我決定廢棄。可是之前已經有太多圍繞貓的方法調用了,因此我加入了註解@Deprecated。IDE中的刪除線就是醒目的標識。工具

哎呀呀,好像調用註解了@Deprecated的方法以後,出現了warning!學習

HappyBKs我是個代碼潔癖,必定要把這個警告去掉。測試

相似的咱們編寫代碼的過程當中,每每不可避免了會出現一些警告,有些咱們能夠根據好的範式、好的習慣、好的經驗把這些代碼從新修改消除警告。可是有時一些場景,彷佛要求咱們包容他們。怎麼辦呢?這時候,能夠用@SuppressWarnings註解,消除相應警告類型。

好比上面的調用廢棄方法產生的警告,咱們能夠改爲這樣:

如今警告沒有了!: )


第三方註解: 

若是你是一個java框架的達人,必定知道spring額@Autowired自動創配,以及@Service和@Repository;也必定會用Mybatis的@InsertProvider,@UpdateProvider,@Option。

做爲用框架的人,少不了和這些第三方註解打交道。這裏就不介紹框架了。


自定義的註解:

若是咱們想讀懂別人的代碼、本身嘗試着寫一下框架、裝裝B格,那麼本身寫一個註解是必不可少的。這也是本系列文章的目標!!


其實要有一類比較特殊的註解,不知道該把它按照哪一個範疇進行劃分,那就是元註解。

元註解:指的是註解的註解。就像元數據是描述數據的數據同樣。具體的我會單獨在一篇文章中介紹。


註解的運行機制、做用域、繼承性等:

我門對註解進行分類,還能夠按照運行機制分類

註解的運行機制:

按照這個運行機制的不一樣,咱們能夠將註解分紅三類:

源碼註解: 註解只在源碼中存在,編譯成.class文件就不存在了。

編譯時註解:註解在.class文件裏面存在。固然在.class文件中存在,在源碼當中固然也是存在的。剛纔說的3個jdk自帶的註解@Deprecated 、@SuppressWarnings、@Override都屬於編譯時註解。也正由於如此,當你@Override了父類不存在的方法,編譯時編譯器會報錯;調用@Deprecated的方法,編譯器會警告。IDE才能在編輯代碼時實時提示錯誤。

運行時註解:在運行階段還起做用,甚至會影響運行邏輯的註解。

如何指定一個註解的運行機制:(即影響的時間點)

咱們在定義一個註解時,還須要指明它是源碼註解、編譯時註解仍是運行時註解。這裏也須要用到一個枚舉:

/*
 * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang.annotation;

/**
 * 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
}


註解的做用域:

註解的做用域指的是一個註解修飾的是什麼語法單元。註解標識的是一個類,一個方法,一個域,一個構造器等等。這裏在指定註解的做用域時會用到一個枚舉來指定做用域的類型,這裏我把jdk的源碼列出:

package java.lang.annotation;

/**
 * A program element type.  The constants of this enumerated type
 * provide a simple classification of the declared elements in a
 * Java program.
 *
 * <p>These constants are used with the {@link Target} meta-annotation type
 * to specify where it is legal to use an annotation type.
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE
}



註解的繼承性:

規定了一個註解在標註了一個類、接口或方法等以後是否會在所在類的子類中生效。這個我會在本系列後面的文章中單獨寫一篇介紹。


註解輸出到文檔:

這個就是@Docmented註解,指定註解是否被輸出到java文檔中。

Documented 註解代表這個註解應該被 javadoc工具記錄. 默認狀況下,javadoc是不包括註解的. 但若是聲明註解時指定了 @Documented,則它會被 javadoc 之類的工具處理, 因此註解類型信息也會被包括在生成的文檔中。


具體如何寫一個本身的註解。放到下一篇文章中寫吧。

相關文章
相關標籤/搜索