Java 註解Anonotation

一、 什麼是註解 html

Annotation表示一種註釋的語法,在 Java 中最先提倡的是程序與配置相分離,而最新的理論是把全部配置直接寫入到代碼中,若是想完成這樣的功能,則使用 Annotation 。 java

 

二、 系統內建的Annotation api

 

2.1  @Override 數組

重寫父類的方法 eclipse

 

2.2  @Deprecated 編輯器

表示不建議使用的操做,若是使用該操做也不報錯,只是在編輯器中出現橫線警告信息,不建議使用。如Date 對像中的不少方法。 ide

@ Deprecated 工具

public   int  getDay ()   { url

     return  normalize () .getDayOfWeek ()  - gcal.SUNDAY; spa

}

 

2.3   @SuppressWaring表示壓制警告,若是出現警告信息,則能夠壓制不提示。 @SuppressWaring 的屬性String[] value() 爲數組,說明能夠同時壓制多個警告。

@ Target ({ TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE })

@ Retention ( RetentionPolicy.SOURCE )

public   @interface   SuppressWarnings  {

     String []  value () ;

}

 

三、自定義 Annotation

 

3.1 語法

public @interface 名稱 {

}


3.2 定義 MyAnnotaion

package  com.chenzehe.annotation;

    public   @interface    MyAnnotation   {

}

若是要使用此Annotation, 則使用 @ 符訪問,不在同一個包中須要導入。以下面 Info 類的使用:

package com.chenzehe.annotation;

@MyAnnotation

public class Info {

}


3.3 Annotation的屬性定義

Annotation的屬性定義以 () 結尾。

package  com.chenzehe.annotation;

public   @interface    MyAnnotation   {

     public  String key () ;

     public  String value () ;

}

上面Annotation 定義了兩個變量 key 和 value ,若是要使用此 Annotation ,則必須明確的給出其內容。如:

package  com.chenzehe.annotation;

@MyAnnotation ( key= "name" ,value= "chenzehe" )

public   class  Info  {

}

 

若是想給Annotation 的變量設置默認值,則使用 default 關鍵字完成,如:

package  com.chenzehe.annotation;

public   @interface    MyAnnotation   {

  public  String key ()   default   "name" ;

    public  String value ()   default   "chenzehe" ;

}

使用此Annotation 時,能夠不用顯示的設置變量值,而使用默認值。


3.4 Annotation中的屬性值能夠經過枚舉限制

定義枚舉類型Color:

package  com.chenzehe.annotation;

public   enum  Color  {

     RED , GLREN , BLUE ;

}

MyAnnotation 中定義一個 Color 類型的變量:

package  com.chenzehe.annotation;

public   @interface    MyAnnotation   {

     public  Color color ()   default  Color. RED ;

}

則使用MyAnnotation 中的 color 變量時,值只能取 Color 中定義的類型:

package  com.chenzehe.annotation;

@MyAnnotation ( color= "red" )

public   class  Info  {

}

上面給變量color 賦值出錯,正確以下:

package  com.chenzehe.annotation;

@MyAnnotation ( color = Color. RED )

public   class  Info  {

}


3.5 Annotation中的屬性爲數組類型

若是Annotation 中的屬性爲數組類型,則使用的時候必須按照數組的方式操做。

package  com.chenzehe.annotation;

public   @interface    MyAnnotation   {

public  String []  urls () ;

}

使用:

package  com.chenzehe.annotation;

@MyAnnotation ( urls =  {   "www.baidu.com"  "g.cn"   })

public   class  Info  {

}

四、 註釋類型 Retention  枚舉 RetentionPolicy

@Documented

@Retention ( value = RUNTIME )

@Target  ( value = ANNOTATION_TYPE )

public @interface  Retention

      指示注  類型的註釋要保留多久 ,也就是做用範圍。 若是註釋類型聲明中不存在 Retention  註釋,則保留策略默認爲  RetentionPolicy.CLASS 。只有元註釋類型直接用於註釋時, Target  元註釋纔有效。若是元註釋類型用做另外一種註釋類型的成員,則無效。

枚舉 RetentionPolicy 定義了三種 Annotation的範圍:

CLASS   在編譯以後的 class文件中做用

RUNTIME   在運行的時候起做用

SOURCE   只在源代碼中起做用

系統內置的三個Annotation 的做用域分別爲:

@ Override  @Retention ( value = SOURCE ) 源碼

@ Deprecated  @Retention ( value = RUNTIME ) 運行時

@ SuppressWarnings  @Retention ( value = SOURCE ) 源碼

 

五、 反射與Annotation

一個Annotation 若是要想起做用,則確定要依賴反射機制,經過反射能夠取得一個方法上聲明的  Annotation所有內容。任何一下自定義的 Annotation 都是繼承了 java.lang.annotation.Annotation 接口。

 Field   Method   Constructor  的父類 AccessibleObject   定義了以下與Annotation 操做相關的方法:

取得所有Annotation  : public  Annotation []   getAnnotations ()   

判斷操做的是不是指定的Annotation : public boolean  isAnnotationPresent ( Class <? extends  Annotation> annotationClass) 

例:下面Info 類中 toString() 方法使用的 Annotation ,在 Test 類中用反射訪問這些 Annotation

package  com.chenzehe.annotation;

public   class  Info  {

     @Override

     @Deprecated

     @SuppressWarnings ( value =  "" )

     public  String  toString ()   {

         return   "Hello World!" ;

     }

}

 

package  com.chenzehe.annotation;

import  java.lang.annotation.Annotation;

import  java.lang.reflect.Method;

public   class  Test  {

     public   static   void  main ( String []  args )   throws  Exception  {

         Class<?> cls = Class. forName ( "com.chenzehe.annotation.Info" ) ;

         Method method = cls.getMethod ( "toString" ) ;

         Annotation []  annotations = method.getAnnotations () ;

         for   ( int   i  = 0;  i  < annotations. length  i ++ )   {

             System. out .println ( annotations [ i ]) ;

         }

     }

}

輸出:@java.lang.Deprecated() ,而 Info 類中使用的三個 Annotation 中,只有 Deprecated 的範圍爲 runtime ,說明只有範圍在 runtime 的才能被找到。

 

MyAnnotation 類改爲 runtime 範圍,並在 Test 類中用反射取得他的屬性:

package  com.chenzehe.annotation;

import  java.lang.annotation.Retention;

import  java.lang.annotation.RetentionPolicy;

@Retention ( value = RetentionPolicy. RUNTIME )

public   @interface    MyAnnotation   {

     public  String key ()   default   "name" ;

     public  String value () ;

}

 Info中使用該 Annotation :

package  com.chenzehe.annotation;

public   class  Info  {

     @Override

     @Deprecated

     @SuppressWarnings ( value =  "" )

     @MyAnnotation ( value= "chenzehe" )

     public   String   toString ()   {

         return   "Hello World!" ;

     }

}

 Test類中使用反射取得其屬性:

package  com.chenzehe.annotation;

import  java.lang.annotation.Annotation;

import  java.lang.reflect.Method;

public   class  Test  {

     public   static   void  main ( String []  args )   throws  Exception  {

         Class<?> cls = Class. forName ( "com.chenzehe.annotation.Info" ) ;

         Method method = cls.getMethod ( "toString" ) ;

         Annotation []  annotations = method.getAnnotations () ;

         for   ( int  i = 0; i < annotations. length ; i++ )   {

             if   ( method.isAnnotationPresent ( MyAnnotation . class ))   {

                 MyAnnotation  myAnnotation = method.getAnnotation ( MyAnnotation . class ) ;

                 String key = myAnnotation.key () ;

                 String value = myAnnotation.value () ;

                 System. out .println ( key +  ":"  + value ) ;

             }

         }

     }

}

 

六、 Target

java.lang.annotation 中已定義的註解類型 Target  ,用於指定所定義的註解使用的範圍爲方法、類、屬性等。

默認狀況下一個自定義的Annotation 能夠在任意地方使用,如自定義的 MyAnnotation ,若是沒有指定 Target ,則能夠在任意地方使用:

package  com.chenzehe.annotation;

@MyAnnotation ()

public   class  Info  {

     @MyAnnotation ()

     private  String name ;

     @MyAnnotation ()

     public  String toString ()   {

         return   "Hello World!" ;

     }

}

Target 的定義中, value 的屬性類型爲   ElementType [] ,所指定的範圍有如下八種:

一、 只能在Annotation 中出現: ANNOTATION_TYPE  

二、 只能在構造方法中出現: CONSTRUCTOR  

三、 在屬性中出現: FIELD  

四、 只能在本地變量中出現: LOCAL_VARIABLE  

五、 在方法上出現: METHOD  

六、 在包聲明中出現: PACKAGE  

七、 在參數聲明中出現: PARAMETER  

八、 類、接口(包括註釋類型)或枚舉聲明 中使用:   TYPE  

如如下自定義的MyAnnotation 只能在方法中使用:

package  com.chenzehe.annotation;

import  java.lang.annotation.ElementType;

import  java.lang.annotation.Retention;

import  java.lang.annotation.RetentionPolicy;

import  java.lang.annotation.Target;

@Retention ( value = RetentionPolicy. RUNTIME )

@Target  ( value= ( ElementType. METHOD ))

public   @interface    MyAnnotation   {

    public  String key ()   default   "name" ;

    public  String value ()   default   "chenzehe" ;

}

Target中的屬性 value 定義爲數組類型,因此能夠同時設置多個 ElementType ,如:

@Target  ( value =  {  ElementType. METHOD , ElementType. FIELD   })

 

七、 Document註解

java.lang.annotation 中定義的註解類型 Documented  , 指示某一類型的註釋將經過 javadoc  和相似的默認工具進行文檔化。應使用此類型來註釋這些類型的聲明:其註釋會影響由其客戶端註釋的元素的使用。若是類型聲明是用  Documented  來註釋的,則其註釋將成爲註釋元素的公共  API  的一部分。 

如聲明 MyAnnotation註解:

package  com.chenzehe.annotation;

import  java.lang.annotation.Documented;

import  java.lang.annotation.ElementType;

import  java.lang.annotation.Retention;

import  java.lang.annotation.RetentionPolicy;

import  java.lang.annotation.Target;

@Documented

@Retention ( value = RetentionPolicy. RUNTIME )

@Target  ( value =  {  ElementType. METHOD , ElementType. FIELD   })

public   @interface    MyAnnotation   {

     public  String key ()   default   "name" ;

     public  String value ()   default   "chenzehe" ;

}

Info 類中使用:

package  com.chenzehe.annotation;

public   class  Info  {

     /**

     * 此方法是覆蓋Object中的toString()方法

     */

     @ MyAnnotation ()

     public  String toString ()   {

         return   "Hello World!" ;

     }

}

能夠經過eclipse 的 export 導出 javadoc ,在其註釋中能看到上面編寫的註釋

 

八、 Inherited

java.lang.annotation 中聲明 Inherited  ,表示該annotation 是否被該子類斷承下去,若是沒有此註解,說明不能被斷承。

如自定義的MyAnnotation ,加入 @Inherited ,說明此 Annotation 能夠被子類斷承:

package  com.chenzehe.annotation;

import  java.lang.annotation.Inherited;

import  java.lang.annotation.Retention;

import  java.lang.annotation.RetentionPolicy;

@Inherited

@Retention ( value = RetentionPolicy. RUNTIME )

public   @interface    MyAnnotation   {

    public  String key ()   default   "name" ;

     public  String value ()   default   "chenzehe" ;

}

 Info類中使用該 Annotation :

package  com.chenzehe.annotation;

@ MyAnnotation

public   class  Info  {

}

建立Info 類的子類 PersonInfo :

package  com.chenzehe.annotation;

public   class  PersonInfo  extends  Info  {

}

使用反射取得PersonInfo 類的 annotation 信息:

package  com.chenzehe.annotation;

import  java.lang.annotation.Annotation;

public   class  Test  {

     public   static   void  main ( String []  args )   throws  Exception  {

         Class<?> cls = Class. forName ( "com.chenzehe.annotation.PersonInfo" ) ;

         Annotation []  annotations = cls.getAnnotations () ;

         for   ( int  i = 0; i < annotations. length ; i++ )   {

             System. out .println ( annotations [ i ]) ;

         }

     }

}

若是MyAnnotation 中加入 @Inherited ,則能夠取到 MyAnnotaion信息,若是沒有加則取不到。

相關文章
相關標籤/搜索