java 注解 基本原理 編程實現


摘要: java 1.5開始引入了注解和反射,正確的來說注解是反射的一部分,沒有反射,注解無法正常使用,但離開注解,反射依舊可以使用,因此來說,反射的定義應該包含注解才合理一些。

java 1.5開始引入了注解和反射,正確的來說注解是反射的一部分,沒有反射,注解無法正常使用,但離開注解,反射依舊可以使用,因此來說,

反射的定義應該包含注解才合理一些。當然,這只是個人想法,至於java官方為什么這么涇渭分明不得而知,最重要的是如何使用注解。

 

注解的功能分為2部分:

  1. 作為特定的標記

  2. 額外信息的載體

 

 定義一個UserAnnotation注解類

1 @Target(value = { ElementType.FIELD })
2 @Retention(RetentionPolicy.RUNTIME)
3 public @interface UserAnnotation {
4     public int id() default 0;
5     public String name() default "";
6     public int age() default 18;
7     public String gender() default "M";
8 }

其中@target個@Retention本身就是注解

【@target】這個注解來指定給哪一類java成員注解,指定注解目標該是什么樣的東西

注解@Target的源碼

 1 @Documented
 2 @Retention(RetentionPolicy.RUNTIME)
 3 @Target(ElementType.ANNOTATION_TYPE) //這不是在作弊,這確實是自己注解自己,所以說注解也可以被字節給注解
 4 public @interface Target {
 5     ElementType[] value(); //值可以使數組 value={...}
 6 }
 7 
 8 public enum ElementType {
 9     TYPE,  //給類(型)注解
10     FIELD, //給字段注解,不要忘了,字段可以是對象
11     METHOD, //給方法注解
12     PARAMETER, //給參數注解
13     CONSTRUCTOR, //給構造方法注解
14     LOCAL_VARIABLE, //給局部變量注解
15     ANNOTATION_TYPE,//給注解注解(這貌似把自己不當類來看)
16     PACKAGE, //給包注解
17     TYPE_PARAMETER, //不知道,等知道了我再寫在這里
18     TYPE_USE //這個也不知道
19 }

【@Retention】表示注解運行的狀態,換句話說,注解改在什么樣的狀態下才能運行

注解@Retention的源碼

 1 @Documented
 2 @Retention(RetentionPolicy.RUNTIME)
 3 @Target(ElementType.ANNOTATION_TYPE)
 4 public @interface Retention {
 5     RetentionPolicy value();
 6 }
 7 
 8 public enum RetentionPolicy {
 9     SOURCE, //源碼狀態運行,
10     CLASS, //編譯類文件時運行
11     RUNTIME //運行時運行
12 }

一般來說,源碼狀態運行和編譯狀態運行的注解往往和編譯器相關,比如報錯,警告,類編譯參數等,這2類狀態一般和編輯器插件關系密切,這里不再討論

在日常開發中RUNTIME用的最多,這是開發人員可以控制的一個狀態。

 

 

【@Documented】額,不多解釋,具體來說是生成說明文檔時把類的解釋添加進去。

 

關於注解的方法說明,注解只有方法,沒有字段,因為注解也是一個interface,只不過前面加了一個@符號,還有一點是這些方法無法實現,寫法和C++的純虛函數相似

請看id()方法的解釋

1  public int id() default 0; 
2 /*首先,方法必須是public的,去掉public,默認也是public,接口interface不也是這樣么
3  *
4  *其次,default默認值不是必須的,方法必須有返回值,返回值可以是java中復雜對象,也可以是基本類型,枚舉都行
5  *如 ElementType[] value();
6  */

注解定義好了,怎么使用呢,如下

 1 public class TestMain
 2 {
 3   @UserAnnotation(age=20,gender="F",id=2014,name="zhangsan")//注解的使用
 4   private Object obj;
 5   
 6   public static void main(String[] args) throws Exception
 7   {
 8      Filed objField = TestMain.class.getField("obj");
 9      UserAnnotation ua = objField.getAnnotation(UserAnnotation.class);//得到注解,起到了標記的作用
10      
11     System.out.println(ua.age()+","+ua.gender()+","+ua.id()+","+ua.name());
12     //***進一步操作的話,假設Object要指向一個User類,那么可以講注解的值給他
13     TestMain tm = new TestMain();
14     objFiled.set(tm,new User(ua.age(),ua.gender(),ua.id(),ua.name())); //不錯吧,將自己的信息送給obj,起到了附加信息的作用
15     
16     //-----------請自由遐想吧~~,下面來說說注解怎么能獲得注解自己的注解-------------
17    Target t = ua.annotationType().getAnnotation(Target.class)
18    ElementType[] values = t.value();
19    //~~~~~~~~~~~~~~完了,再一次自由遐想吧~~~~~~~~~~~~~~
20    
21    Sysout.out.println("注意:是遐想,不是瞎想!!");
22   }
23 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM