1. 程式人生 > >註解(Annotation)的使用.

註解(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);
            }
        }
    }
}