註解這東西,已經在咱們的編程生活中習覺得常了。覆蓋一個父類的方法,套用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 之類的工具處理, 因此註解類型信息也會被包括在生成的文檔中。
具體如何寫一個本身的註解。放到下一篇文章中寫吧。