Java基礎-Java註解
註解的基本概念
註解為我們在程式碼中新增資訊提供了一種形式化的方法,使我們可以在稍後某個時刻非常方便地使用這些資料。
定義註解的方式
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test{
}
如上面程式碼中看到的,一個簡單的自定義註解就這樣誕生了。有的同學可能會奇怪,為什麼需要有@Target,@Retention這兩個註解來修飾我們自定義的註解@Test呢?原來當我們在定義註解時,需要用元註解來對我們的註解進行一定的說明。@Target用來定義你的註解將應用於什麼地方(例如是一個方法或者一個域)。@Retention用來定義該註解在哪一個級別可用,在原始碼中(SOURCE),在類檔案中(ClASS)或者在執行時(RUNTIME)。
元註解
上面我們在自定義註解時,發現我們需要元註解來幫忙,那元註解到底有哪些呢?他們分別起的作用有事什麼呢?讓我們來一起看一下。
元註解 | 說明 |
---|---|
@Target | 表示該註解可以用於什麼地方。可能的ElementType引數包括:CONSTRUCTOR:構造器的宣告。 FIELD:域宣告(包括enum例項)。LOCAL_VARIABLE:區域性變數宣告。METHOD:方法宣告。PACKAGE:包宣告。PARAMETER:引數宣告。TYPE:類,介面(包括註解類)或enum宣告。 |
@Retention | 表示需要在什麼級別儲存該註解資訊。可選的RetentionPolicy引數包括:SOURCE:註解將被編譯器丟棄。CLASS:註解在class檔案中可用,但會被VM丟棄。RUNTIME:VM將在執行期也保留註解,因此可以通過反射機制讀取註解的資訊。 |
@Documented | 將此註解包含在javadoc中。 |
@Inherited | 允許子類繼承父類中的註解。 |
註解元素
在註解中我們是可以自定義元素的。但是是不是所有的型別都可以作為註解的元素呢?下面我們一起來看一下Java中對註解元素的規定。 1. 所有基本型別(int,float,boolean,double,long等) 2. String 3. Class 4. enum 5. Annotation 6. 以上型別的陣列
這裡需要強調一下的是:不允許使用任何包裝型別
預設值限制
在給我們自己定義的註解添加註解元素的時候,我們是可以給這些註解元素新增預設值的,這裡對預設值有有一些要求,主要是一下兩點: 1. 元素不能有不確定的值。也就是說,元素必須要麼具有預設值,要麼在使用註解時提供元素的值。 2. 對於非基本型別的元素,無論在原始碼中宣告時,或是在註解介面中定義預設值時,都不能以null為其值。
動手試一試
寫了這麼多概念性的東西,感覺是時候動手寫一下了。 首先我們自定義一個註解,
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationTest{
public String name() default "";
public int code() default 0;
public Class clazz() Object.class;
}
然後我們定義一個實體類
public class AnnotationModel{
@AnnotationTest(name="時間",code=1,clazz=Date.class)
public Date startDate;
public Date getStartDate(){
return startDate;
}
public void setStartDate(Date date) {
this.startDate = date;
}
}
最後,我們通過反射的方法獲取到定義到FIELD中的註解資訊。
public class AnnotationMain{
public static void main(String[] args) {
Class<?> modelClazz = AnnotationModel.class;
Field[] fields = modelClazz.getDeclaredFields();
for(Field field : fields) {
// 獲取指定的註解
AnnotationTest annotationTest = field.getAnnotation(AnnotationTest.class);
if(null == annotationTest) {
continue;
}
System.out.println(annotationTest.name);
System.out.println(annotationTest.code);
System.out.println(annotationTest.clazz);
}
}
}
寫到這裡就差不多了,後面還有巢狀註解,感興趣的同學可以自己嘗試一下。