註解專題(一)Java元註解,內建註解

vslegend發表於2018-07-21

剛剛接觸企業級應用開發,進入公司學習了也快滿一個月了,這次就來寫一些專案過程中遇到的一些常用註解,一方面加深理解,一方面也算是總結。

宣告:不足之處甚多,還望各位一一指正。

注意:註解大小寫敏感。

目前學習思路

  1. Java元註解,內建註解
  2. 註解實現機制,原理剖析
  3. 自定義註解的編寫
  4. Spring註解歸納
  5. 總結

 

1. 提要:

Java5.0 發行版本中新增的引用型別,一種新的介面稱為:註解型別。

註解型別的直接超介面始終是Annotation(java.lang.annotation.Annotation)註解介面,但這並不意味著一個介面實現該介面就是註解型別了,該介面並不定義註釋型別。事實上,Annotation本身也並不是註解型別(也可以從原始碼中看出,Annotation介面並沒有註解標記@ Interface),因為註解型別無法顯式宣告超類或超介面這一事實的結果是註解型別的子類或子介面本身永遠不是註解型別。

2. Java元註解:

元註解(meta-annotation),是用於註解其他註解的一種註解,這很好理解,元註解為其他任意註解(包含元註解本身)的生命週期,作用物件,是否將該註解寫入javadoc以及該註解是否可被繼承提供一種標準,以該標準來建立新的註解。(註解的所有引數都可以在原始碼中檢視,原始碼中都有相應的註釋)

  • @Target:表示該註解可用於什麼地方。請注意,下面的列舉常量僅可在其引數中出現一次,否則會在編譯時出錯。(It is a compile-time error if a given enum constant appears more than once in an annotation whose corresponding type is java.lang.annotation.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(列舉類)引數有:

TYPE:類,介面(註解介面),enum宣告

FIELD:欄位宣告(包括enum常量)

METHOD:方法宣告

PARAMETER:形參宣告

CONSTRUCTOR:建構函式宣告

LOCAL_VARIABLE:區域性變數宣告

ANNOTATION_TYPE:註解宣告

PACKEGE:包宣告

 

  • @Retention:宣告該註解會保留多久。預設為RetentionPolicy.CLASS。
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Retention {
        /**
         * Returns the retention policy.
         * @return the retention policy
         */
        RetentionPolicy value();
    }

     

RetentionPolicy引數有:

SOURCE:註解會被編譯器丟棄。(僅原始檔中)

CLASS:註解通過編譯器儲存在class檔案中,但是在VM在執行期不會保留註解。預設操作,此為預設值。(作用於class檔案中)

RUNTIME:註解通過編譯器儲存在class檔案中,並且VM在執行期也保留註解,因此可以通過反射機制讀取註解資訊。(作用於執行期)

 

  • @Documented:當一個註解介面被@Documented註解後,那麼這個註解就會成為帶有註解元素的公共API的一部分(If a type declaration is annotated with Documented, its annotations become part of the public API of the annotated elements.),一般來說,javadoc(javadoc從程式原始碼中抽取類、方法、成員等註釋形成一個和原始碼配套的API幫助文件)是不會包括註解的。有關javadoc的內容可以查閱相關的資料。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

 

  • @Inherited:允許子類繼承父類或超類的註解。但是對介面無效,這一點可以從 提要 中知曉。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

小結:在註解介面中,若它沒有引數(如@Inherited ,@Documented),則稱為標記註解,只用於標記被註解的元素(類似於標記介面,如Serializable  Cloneable等介面)

 

2. Java內建註解:

  • @Override:常用註解,用於當前類覆蓋其超類的方法,這裡就不多贅述了。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
  • @Deprecated  :在物件呼叫使用了@Deprecated註解的方法時,發出警告,示意該方法已經過時。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
public class Anno {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Game w=new Game();
		w.gameLOL();
	}
public static class Game{
	Game(){}
	@Deprecated
	void gameLOL()
	{
		System.out.println("Warning:This game has been deprecated");
	}
}
}

在編譯器中,使用該註解,會將被註解的方法畫上橫槓,以示意方法已經棄用。實際開發中,因為業務需求的變更臨時放棄該功能,或者有其他暫時性替代該方法的功能,但不確定該方法會不會再次啟用時,就可以使用@Deprecated註解。

 

  • @SuppressWarnings:關閉編譯器不當的訊息警告
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

通過其原始碼中的註解@Target可以看到,該註解可以標註的目標有:類(或介面),欄位,方法,引數,建構函式,區域性變數。

在上面的示例程式碼中,我們想消除物件使用gameLOL()方法時的警告,就可以新增@SuppressWarnings("deprecation")註解關閉警告。(不過常規來講,以上做法是自相矛盾的)

@SuppressWarnings(value="關鍵字") ,當只有一個關鍵字時,value可以省略。該註解通過關鍵字的方式來選擇需要關閉的訊息警告。一些常用的關鍵字:all,deprecation,null,unchecked(沒怎麼用到過該註解,所有沒有做過深入瞭解。)

  • 小結:可以看到,Java內建的三種註解,其中@Override @SuppressWarnings 都是在原始檔中生效,@Deprecated在執行時生效,然而事實上也正是如此。

3. 總結:

本篇文章描寫了註解的基本資訊,四種元註解的講解,以及Java內建註解的簡單梳理。內容大多都是通過查閱原始碼,API文件,以及官方文件資料瞭解。

相關文章