java中的註解(Annotation)仍是要知道一些滴

認識註解

註解的初識在自動生成重寫諸如equals()等方法時頭頂的那個@Override,還有消除那黃黃的警告線時的@SuppressWarnings,當時只是感受無關緊要的東西,對它就像只是看待一個不知道哪兒定義的一個方法而已。java

以後感受它的神奇就是在項目使用框架時了。學習框架時用的xml配置,已經感受挺有創意了,並無學習annotation,在一次實際項目開發中,hibernate,spring,springMVC統統註解。那簡潔的xml配置和一行代碼頂數句的註解更是感到神氣的不行(xml與註解各有好處,非是誤導註解必定強於xml),而後纔對註解另眼相看,準備多學習一些。spring


我的信息
註解出生時間在jdk 1.5版本。地位呢,他是一個類型,地位同於class(類),interface(接口),固然還有一個平級可是和它同樣不是很是常見的類型:enmu(枚舉)。數據庫

項目經歷
Hibernate中,用註解能夠實現字段與數據庫列的映射。api

Spring中註解更是用着舒服,不管是Io仍是AOP的配置,使用註解效率比起xml配置都是快捷不少。並且也是在框架學習時較多的使用註解,發現註解的強大。也由此以爲再使用的基礎上應該有一些進一步的瞭解。數組

其餘框架中如Junit 4版本開始後也是註解@Test代替了命名規則,數不勝數,相信在以後開發中,註解會被越來多的使用。框架

技能分類ide

註解有三種類型工具

  1. 自定義註解:顧名思義,就是本身寫的註解了,具體的實如今以後說明。
  2. 內置註解: 也就是jdk中本身定義的註解,如以前所說@Override等都是。
  3. 元註解: 能夠註解在註解上的註解(看起來有點繞口,不錯~)
package java.lang;
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

如上代碼,這是源碼中的@Override代碼,這個其實就是個自定義註解(我的想法),只不過是jdk本身寫的,因此他就是內置註解
其中有兩行學習

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)

這兒的@Target@Retention就是元註解。固然不止這兩個。測試

  1. Documented 指示某一類型的註釋將經過 javadoc 和相似的默認工具進行文檔化。
  2. Inherited 指示註釋類型被自動繼承。
  3. Retention 指示註釋類型的註釋要保留多久。
  4. Target 指示註釋類型所適用的程序元素的種類。

具體的定義以及參數的解釋在API文檔或者源碼【幫您找好】中java.lang.annotation包均可以很明確的瞭解。包括內置註解均可以直接看jdk中的具體實現。

實踐

在文檔或jdk中元註解以及內置註解自定義都有源碼參考,所以再須要瞭解的即是自定義註解。

自定義註解有三個:

  1. 定義一個註解。在源碼中和平時不同的就是那個@interface,他於註解就至關於class於一個類,用@interface聲明要定義的是一個註解,後面跟的天然是註解名稱了。
  2. 應用一個註解。註解定義後,根據定義的適用範圍(類,方法,字段等等)使用註解。註解不會直接影響原有代碼,無論運行仍是什麼的
  3. 處理註解。在2中說註解不會影響代碼,也許會想到不影響那怎麼注入了,驗證了等等。註解不會影響,可是處理註解就影響了。註解至關於給牆上打了個‘拆’字,這個不會對房子有任何損壞(別說影響美觀~),可是挖掘機看見‘拆’字就會撲上去,這就不能保證房子的安然了。這兒對註解(能保留到運行期)的處理通常經過java中的反射機制來實現。

註解參數類型:

  1. 全部基本數據類型(int,float,boolean,byte,double,char,long,short)
  2. String、Class、enum、Annotation類型
  3. 以上全部類型的數組

舉個栗子:

//1. 定義兩個註解 StuId(用來講明學號)    StuSex(用來定義性別)

@Target(ElementType.FIELD)//做用於字段上
@Retention(RetentionPolicy.RUNTIME)//保留到運行期
public @interface StuId{
    /**此處定義成員也就是用註解時要傳遞的相似於參數的玩意,指定了默認值,使用時能夠不寫字段值
    *不然必須寫:如 @StuId(stuId = "0001") 
    *若是是單一屬性 通常聲明爲 String value(); 
    *這樣在使用時能夠簡寫爲 @StuId("0001")
    */
    String stuId() default "000";//使用時能夠 @StuId  字段值會取默認值000
    
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface StuSex{
    public enum sex{
        男,女;
    }
    sex stuSex() default sex.男;
}

//2. 使用註解(房子寫個"拆")
public class Student{
    
    //給字段注值應該在set方法上,字段上破壞了封裝性,此處無視~
    
    @StuId(stuId = "0001")
    private String stuId;
    
    @StuSex(stuSex = sex.女)
    private String stuSex;
    
    //...省略getter和setter
}
//3. 處理註解(出動挖掘機...)
public static void getStuInfo(Class<?> clazz){
    Field[] fields = clazz.getDeclaredFields();
        
    for(Field field :fields){
        //找出其中是StuId類型的註解
        if(field.isAnnotationPresent(StuId.class)){
            StuId stuId = (StuId) field.getAnnotation(StuId.class);
            System.out.println("學號:"+stuId.stuId());
        }
        //找出其中是StuSex類型的註解
        else if(field.isAnnotationPresent(StuSex.class)){
            StuSex stuSex= (StuSex) field.getAnnotation(StuSex.class);
            System.out.println("性別:"+stuSex.stuSex());
        }
    }
}

//如上註解已經完成,下來測試:
public class Test {
    public static void main(String[] args) {
        DellStu.getStuInfo(Student.class);
    }
}

輸出結果:
學號:0001
性別:女
//回看 2.註解使用 ,若是是這樣,不寫字段值
    @StuId(stuId = "0001")
    private String stuId;
    
    @StuSex(stuSex = sex.女)
    private String stuSex;
//那麼輸出結果(註解定義時設置的默認值):
學號:000
性別:男

我的評價 通常狀況下是用不到本身去實現一個註解的,只有開發框架什麼的大牛們纔會用到(爲了給我這菜鳥用...),可是仍是有必要簡單瞭解一些。

相關文章
相關標籤/搜索