天天看點

Java自定義注解[一]

1:注解【Annotation】是JDK1.5之後新增的重要特性,通過注解,程式開發人員可以在不改變原有邏輯的情況下,在源檔案中嵌入一些補充的資訊。

Annotation可以用來修飾類,屬性,方法,而且Annotation不影響程式的運作,無論是否使用Annotation代碼都可以正常的執行。

java.lang.annotation.Annotation是Annotation的接口,隻要是Annotation都必須實作此接口,其定義如下:

public abstract interface Annotation {
    // 傳回此Annotation的注釋類型
    public abstract Class<? extends Annotation> annotationType();

    public abstract boolean equals(java.lang.Object arg0);

    public abstract int hashCode();

    public abstract java.lang.String toString();
}
           

2:JDK5之後,系統内建了3個Annotation類型,使用者直接使用即可。

         @Override:覆寫的Annotation
	 @Deprecated:不贊成使用的Annotation
	 @SuppressWarnings:壓制安全警告的Annotation
           

2.1:@Override主要在方法覆寫時使用,用于確定方法覆寫的正确性。如下所示:

// 父類Person
class Person {
	protected String name;
	public Person(String name) {
		super();
		this.name = name;
	}
	public String getInfo1() {
		return "這是父類Person,名字是:" + name;
	}
	public String getInfo2() {
		return "這是父類Person,名字是:" + name;
	}
}
           
Java自定義注解[一]

可以發現,使用@Override注解後,錯誤的方法覆寫會給出提示,是以,使用@Override注解可以確定方法被正确覆寫。

@Override隻能使用在方法上,而其他元素,包括類,屬性上是不能使用的。

2.2:@Deprecated注釋的主要功能是用來聲明一個不建議使用的方法或類或屬性等,如果在程式中使用了此注解,則會在編譯時出現警告資訊。依然以Person類為例:

Java自定義注解[一]

雖然有警告資訊,但是程式依然可以正常執行,隻是不建議使用,并不是不能使用。依然使用Student類繼承Person類:

Java自定義注解[一]

可以發現父類Person會有警告提示,但方法的警告并未被繼承下來

Java自定義注解[一]

補充:警告不建議使用的方法有很多,比如Thread類中的suspend(),stop(),resume()三個方法不建議使用,實際上就是使用了@Deprecated注釋聲明的。

2.3:@SuppressWarnings注釋主要是用于壓制警告,當程式産生警告,但警告并不影響程式正确執行時,就可以使用@SuppressWarnings注解,這樣可以讓代碼看起來潔淨。

比如在聲明集合時沒有指定泛型:

Java自定義注解[一]

這裡出現了兩個警告,它們代表的含義并不相同:

Java自定義注解[一]

rawtypes 是指傳參時也要傳遞帶泛型的參數;unused  是指定義的變量在代碼中并未使用且無法通路

我們發現@SuppressWarnings注解可以同時傳遞多個參數,是按照資料的格式操作的。

public static void main(String[] args) {
		@SuppressWarnings(value={ "rawtypes", "unused" })
		List list = new ArrayList<String>();
	}
           

在設定注解的時候,是以"key-value”的形式出現的。

以上簡要的介紹了注解的使用及其作用。

接下來,我們來了解注解的聲明

3:元注解

元注解是指注解的注解。包括 @Target, @Retention,@Document ,@Inherited四種

3.1:@Target 注解

一個Annotation如果沒有明确的指明定義的位置,則可以再任何地方使用。如果希望一個自定義的注解隻能再指定的位置出現,例如像@Override隻能出現在方法上,則必須使用@Target注釋。以@Override為例:

@java.lang.annotation.Target(value={java.lang.annotation.ElementType.METHOD})
@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.SOURCE)
public abstract @interface java.lang.Override extends java.lang.annotation.Annotation {

}
           

可以發現,@Override的聲明範圍為METHOD,是以它隻能出現在方法上,而不能出現在其他地方,否則會報錯

Java自定義注解[一]

如圖所示,當@Override出現在類上時,會報錯。

@Target的範圍為:

@Target(ElementType.TYPE)   //接口、類、枚舉、注解
@Target(ElementType.FIELD) //字段、枚舉的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法參數
@Target(ElementType.CONSTRUCTOR)  //構造函數
@Target(ElementType.LOCAL_VARIABLE)//局部變量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包 
           

3.2:@Retention注解

@Retention用于聲明注解的保留位置,有三個取值

@Retention(RetentionPolicy.SOURCE)   //注解僅存在于源碼中,在class位元組碼檔案中不包含
@Retention(RetentionPolicy.CLASS)     // 預設的保留政策,注解會在class位元組碼檔案中存在,但運作時無法獲得,
@Retention(RetentionPolicy.RUNTIME)  // 注解會在class位元組碼檔案中存在,在運作時可以通過反射擷取到  
           

将注解聲明為在程式執行時起作用是一種比較常見的使用方法,而如果設定為其他範圍,則以後再Annotation的應用中肯定是無法通路到的。

3.3:@Document注解

任何一個自定義的Annotation實際上多上都是通過@Document進行注釋的。指明擁有這個注解的元素可以被javadoc此類的工具文檔化。這種類型應該用于注解那些影響客戶使用帶注釋的元素聲明的類型。如果一種聲明使用@Document進行注解,這種類型的注解被作為被标注的程式成員的公共API。

3.4:@Inherited注解

用于辨別一個父類的注解是否可以被子類所繼承。如果使用者在目前類中查詢這個元注解類型并且目前類的聲明中不包含這個元注解類型,那麼也将自動查詢目前類的父類是否存在Inherited元注解,這個動作将被重複執行知道這個标注類型被找到,或者是查詢到頂層的父類。

------未完待續.......................