註解(Annotation)的使用.
1.什麼是註解:
註釋: 給程式設計師看的. 註解: 給JVM看的 , 可以加在包、類、欄位、方法、區域性變數、方法引數等前面 , 用來對這些元素說明 , 註釋. 注: 一個同名的註解只能使用一次.
2.註解的作用:
- 編寫文件: 通過程式碼裡標識的註解生成文件. [ 例: 生成doc文件 ]
- 程式碼分析: 對程式碼進行分析. [ 例: 註解的反射 ]
- 編譯檢查: 讓編譯器能夠實現基本的編譯檢查. [ 例: Override ]
3.自定義註解:
定義格式: 元註解 public @interface 註解名稱{ 格式1: 修飾符 資料型別 屬性名( ); 格式2: 修飾符 資料型別 屬性名( ) default
預設值 ; } 註解的屬性: 1.作用: 使用註解時可以傳遞引數 , 讓註解功能更強大. 2.屬性使用的資料型別: 四類八種 , String型別 , Class 型別 , 列舉 , 註解型別. 3.特殊屬性Value : 當只有一個屬性 && 名稱是value , 可以直接給屬性值. 使用格式: 沒有屬性: @註解名稱 有 屬 性 : @註解名稱(屬性名 = 屬性值 , 屬性名 = 屬性值 … ) value屬性: @註解名稱(屬性值) ;
自定義註解案例:
/* 定義一個註解:Book - 包含屬性:String name() 書名 - 包含屬性:double price() 價格,預設值為 100 - 包含屬性:String[] authors() 多位作者 */ public @interface Book { // 書名 public abstract String name(); // - 包含屬性:double price() 價格,預設值為 100 public abstract double price() default 100; // - 包含屬性:String[] authors() 多位作者 public abstract String[] authors(); } // 定義方法使用 public class TestBook { // 有預設值的可以不傳屬性值 , 也可以傳 . @Book(name = "西遊記" , authors = "孫悟空" ,price = 88.88) public void showBook(){ } }
4.註解之元註解: 用於修飾自定義的註解.
元註解之@Target: 作用: 指明用在哪個位置. 可選引數值: ElementType(列舉型別.) type: 用在類 , 介面上 . field: 用在成員變數上 . method: 用在方法上 . parameter: 用在引數上 . constructor: 用在構造方法上. local_variable: 用在區域性變數上.
元註解之@Retention: 作用: 定義該註解的生命週期(有效範圍) 可選引數值: RetentionPolicy: source: 只存在於java原始碼中 . class: 存在於java原始碼中 , 編譯以後的位元組碼檔案中 runtime: 存在於java原始碼中 , 編譯後的位元組碼檔案中 , 執行時記憶體中 . (可通過反射獲取註解)
註解解析: 通過java技術獲取註解資料的過程. 看程式(就是獲取註解的屬性值) isAnnotationPresent( ): 判斷(類上,方法上…)是否有指定的註解 引數傳遞: 要判斷註解的class檔案物件 getAnnotation(): 獲取(類上 ,方法上…)的註解. 引數傳遞: 要獲取的註解的class檔案物件.
綜合案例:
/*
反射和註解的綜合練習題
模擬註解@Test
自定義一個註解@MyTest,並新增元註解(執行中有效,只能用在方法上)
定義一個使用@MyTest類,定義多個方法,部分方法使用@MyTest註解
獲取測試類中所有的方法,判斷方法上是否有@MyTest註解
有:讓方法執行 invoke(obj)
沒有:就不執行方法
*/
// 自定義一個註解@MyTest,並新增元註解(執行中有效,只能用在方法上)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}
// 定義一個類 , 定義多個方法 , 部分方法使用MyTest註解 .
public class TestMyTest {
@MyTest
public void method01(){
System.out.println("method01");
}
public void method02(){
System.out.println("method02");
}
public void method03(){
System.out.println("method03");
}
@MyTest
public void method04(){
System.out.println("method04");
}
}
// 獲取測試類中所有的方法,判斷方法上是否有@MyTest註解
public class Demo01Annotation {
public static void main(String[] args) throws Exception {
// 建立class檔案物件 .
Class<?> clazz = Class.forName("demo07_annotation_$.TestMyTest");
// 獲取例項化物件.
Object o = clazz.newInstance();
// 獲取測試類中所有的方法 .
Method[] methods = clazz.getMethods();
for (Method method : methods) {
// 判斷方法上是否有@MyTest註解
boolean b = method.isAnnotationPresent(MyTest.class);
if(b){
// 有:讓方法執行 invoke(obj)
Object o1 = method.invoke(o);
System.out.println(o1);
}
}
}
}