中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

深入理解Java:注解

注解(jie)作(zuo)用(yong):每當你創建描述符性質的類或者接口時,一旦其(qi)中(zhong)包含重復性的工作(zuo),就(jiu)可(ke)以考慮(lv)使用(yong)注解(jie)來簡化與自動化該過程。

Java提供(gong)了(le)四種元注解,專門負(fu)責新注解的創(chuang)建工作。

 

元注解

  元(yuan)注(zhu)解(jie)的作(zuo)(zuo)用(yong)就是負(fu)責注(zhu)解(jie)其(qi)他注(zhu)解(jie)。Java5.0定(ding)義了(le)4個(ge)標準的meta-annotation類(lei)(lei)型,它們被用(yong)來(lai)提供(gong)對其(qi)它 annotation類(lei)(lei)型作(zuo)(zuo)說明。Java5.0定(ding)義的元(yuan)注(zhu)解(jie):
    1.@Target,
    2.@Retention,
    3.@Documented,
    4.@Inherited
  這些(xie)類型(xing)和它們所支持的類在(zai)java.lang.annotation包中可以(yi)找(zhao)到。下面我們看(kan)一(yi)下每個元注解的作用和相應分參(can)數(shu)的使(shi)用說(shuo)明(ming)。

 

@Target

   @Target說明了Annotation所修飾的(de)對象范圍:Annotation可被用于(yu) packages、types(類、接口、枚舉(ju)、Annotation類型(xing))、類型(xing)成員(方法、構造方法、成員變(bian)量(liang)、枚舉(ju)值(zhi))、方法參數和本地變(bian)量(liang)(如循環變(bian)量(liang)、catch參數)。在Annotation類型(xing)的(de)聲(sheng)明中使用了target可更加明晰其修飾的(de)目標(biao)。

  作用:用于描述注解的使用范圍(即:被描述的注解可以用在什么地方)

  取值(ElementType)有:

    1.CONSTRUCTOR:用于描(miao)述構造器
    2.FIELD:用于描述域
    3.LOCAL_VARIABLE:用(yong)于描述局部變量
    4.METHOD:用于描述方(fang)法
    5.PACKAGE:用于描述(shu)包
    6.PARAMETER:用于(yu)描述參數
    7.TYPE:用于(yu)描述(shu)類、接口(kou)(包括(kuo)注(zhu)解(jie)類型) 或enum聲明

使(shi)用示(shi)例:

/***
 *
 * 實體注解接口
 */
@Target(value = {ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Entity {
    /***
     * 實體默(mo)認firstLevelCache屬性(xing)為false
     * @return boolean
     */
    boolean firstLevelCache() default false;
    /***
     * 實體默認secondLevelCache屬性為false
     * @return boolean
     */
    boolean secondLevelCache() default true;
    /***
     * 表名默(mo)認為空
     * @return String
     */
    String tableName() default "";
    /***
     * 默(mo)認以(yi)""分割(ge)注解(jie)
     */
    String split() default "";
}

 

 

@Retention

  @Retention定義了該Annotation被保留的時間長短:某些Annotation僅出現在源代碼中,而被編譯器丟棄;而另一些卻被編譯在class文件中;編譯在class文件中的Annotation可能會被虛擬機忽略,而另一些在class被裝載時將被讀取(請注意并不影響class的執行,因為Annotation與class在使用上是被分離的)。使用這個meta-Annotation可以對 Annotation的“生命周期”限制。

  作用:表示需要在什么級別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內有效)

  取值(RetentionPoicy)有:

    1.SOURCE:在源文件(jian)中有(you)效(xiao)(即源文件(jian)保留)
    2.CLASS:在class文件中有效(即(ji)class保留)
    3.RUNTIME:在運行時有效(xiao)(即運行時保(bao)留)

 

使用(yong)示例:

/***
 * 字段注解接口
 */
@Target(value = {ElementType.FIELD})//注解可以(yi)被添加在(zai)屬性上
@Retention(value = RetentionPolicy.RUNTIME)//注(zhu)解(jie)保存在JVM運行時(shi)刻,能夠在運行時(shi)刻通過反射API來獲取到(dao)注(zhu)解(jie)的(de)信息
public @interface Column {
    String name();//注解(jie)的name屬(shu)性
}

Column注(zhu)解(jie)的(de)(de)的(de)(de)RetentionPolicy的(de)(de)屬性值是RUTIME,這樣注(zhu)解(jie)處理器(qi)可(ke)以通(tong)過反射,獲取到該注(zhu)解(jie)的(de)(de)屬性值,從而去做一(yi)些運行時的(de)(de)邏輯處理

 

@Documented

  @Documented用于描述其它類型的annotation應該被作為被標注的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。Documented是一個標記注解,沒有成員。

@Inherited

  @Inherited 元注解是一個標記注解,@Inherited闡述了某個被標注的類型是被繼承的。如果一個使用了@Inherited修飾的annotation類型被用于一個class,則這個annotation將被用于該class的子類。

  注(zhu)意(yi):@Inherited annotation類型(xing)是被標注(zhu)過的class的子類所繼承。類并(bing)不(bu)從它(ta)所實現(xian)的接口繼承annotation,方(fang)(fang)法(fa)并(bing)不(bu)從它(ta)所重載(zai)的方(fang)(fang)法(fa)繼承annotation。

  當@Inherited annotation類(lei)(lei)型(xing)標注的(de)annotation的(de)Retention是(shi)RetentionPolicy.RUNTIME,則反(fan)射API增強(qiang)了這種繼承(cheng)性。如果我們(men)使用java.lang.reflect去查(cha)(cha)詢一(yi)個@Inherited annotation類(lei)(lei)型(xing)的(de)annotation時,反(fan)射代(dai)碼檢(jian)查(cha)(cha)將展(zhan)開工作:檢(jian)查(cha)(cha)class和其父(fu)類(lei)(lei),直到(dao)發(fa)現指定(ding)的(de)annotation類(lei)(lei)型(xing)被發(fa)現,或者(zhe)到(dao)達類(lei)(lei)繼承(cheng)結構(gou)的(de)頂層(ceng)。

 

自定義注解

  使用(yong)@interface自定(ding)義注(zhu)(zhu)解(jie)時,自動(dong)繼(ji)承了(le)java.lang.annotation.Annotation接口,由編譯程序自動(dong)完成(cheng)其(qi)他細節。在定(ding)義注(zhu)(zhu)解(jie)時,不能繼(ji)承其(qi)他的(de)(de)(de)(de)注(zhu)(zhu)解(jie)或接口。@interface用(yong)來聲(sheng)明一(yi)個注(zhu)(zhu)解(jie),其(qi)中的(de)(de)(de)(de)每(mei)一(yi)個方法實(shi)際上是(shi)聲(sheng)明了(le)一(yi)個配置參數(shu)。方法的(de)(de)(de)(de)名稱就是(shi)參數(shu)的(de)(de)(de)(de)名稱,返回值(zhi)類型(xing)就是(shi)參數(shu)的(de)(de)(de)(de)類型(xing)(返回值(zhi)類型(xing)只能是(shi)基(ji)本類型(xing)、Class、String、enum)。可以通過default來聲(sheng)明參數(shu)的(de)(de)(de)(de)默認值(zhi)。

  定義注解格式:
  public @interface 注解(jie)名 {定義體}

  注解參數的可支持數據類型:

    1.所(suo)有基本數據類型(int,float,boolean,byte,double,char,long,short)
    2.String類型(xing)
    3.Class類型
    4.enum類型
    5.Annotation類(lei)型
    6.以上所有(you)類型的數組

  Annotation類型里(li)面的(de)參數該(gai)怎么設定: 
  第(di)一,只能用public或默認(ren)(default)這兩個訪問權修飾.例(li)如,String value();這里把方法設為defaul默認(ren)類(lei)型(xing);   
  第二,參數(shu)(shu)(shu)成員只能用基(ji)本(ben)類型byte,short,char,int,long,float,double,boolean八種基(ji)本(ben)數(shu)(shu)(shu)據類型和 String,Enum,Class,annotations等數(shu)(shu)(shu)據類型,以及這一些類型的(de)數(shu)(shu)(shu)組.例(li)如,String value();這里(li)的(de)參數(shu)(shu)(shu)成員就為String;  
  第三,如果只有(you)一個參(can)數(shu)成員,最好把(ba)參(can)數(shu)名稱設為"value",后加小括(kuo)號.例:下面的例子FruitName注解就只有(you)一個參(can)數(shu)成員。

  簡單的自定義注(zhu)解和使用注(zhu)解實例:

示例1:

/***
 *主鍵注解接(jie)口
 */
@Target(value = {ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Id {
}

 

示例2:

/**屬性不需要被持久化注(zhu)解**/
@Target(value = {ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface Transient {
}

注解元素的默認值:

  注解元素必須有確定的值,要么在定義注解的默認值中指定,要么在使用注解時指定,非基本類型的注解元素的值不可為null。因此, 使用空字符串或0作為默認值是一種常用的做法。這個約束使得處理器很難表現一個元素的存在或缺失的狀態,因為每個注解的聲明中,所有元素都存在,并且都具有相應的值,為了繞開這個約束,我們只能定義一些特殊的值,例如空字符串或者負數,一次表示某個元素不存在,在定義注解時,這已經成為一個習慣用法。

 

定義了注(zhu)(zhu)解(jie),并在需要的(de)(de)時(shi)候(hou)給(gei)相關(guan)類,類屬性加上(shang)注(zhu)(zhu)解(jie)信(xin)(xin)息,如果沒有響(xiang)應的(de)(de)注(zhu)(zhu)解(jie)信(xin)(xin)息處(chu)理(li)流程,注(zhu)(zhu)解(jie)可以(yi)說是沒有實(shi)用價值。如何讓注(zhu)(zhu)解(jie)真真的(de)(de)發揮作(zuo)用,主要就(jiu)在于注(zhu)(zhu)解(jie)處(chu)理(li)方法,下一(yi)步我們將學習(xi)注(zhu)(zhu)解(jie)信(xin)(xin)息的(de)(de)獲取和(he)處(chu)理(li)!

 

如果沒有(you)用(yong)(yong)來讀(du)取(qu)注(zhu)解的(de)(de)方(fang)法和工作,那么注(zhu)解也就(jiu)不會比注(zhu)釋更(geng)有(you)用(yong)(yong)處(chu)了(le)。使用(yong)(yong)注(zhu)解的(de)(de)過(guo)程(cheng)中,很(hen)重要的(de)(de)一部分(fen)就(jiu)是創建于使用(yong)(yong)注(zhu)解處(chu)理器。Java SE5擴展(zhan)了(le)反(fan)射機制的(de)(de)API,以幫助程(cheng)序員快速的(de)(de)構造自(zi)定義(yi)注(zhu)解處(chu)理器。

注解處理器類庫(java.lang.reflect.AnnotatedElement):

  Java使用Annotation接(jie)(jie)口來代表(biao)程(cheng)序(xu)元素前(qian)面的(de)注(zhu)解,該接(jie)(jie)口是所有(you)Annotation類型的(de)父接(jie)(jie)口。除(chu)此(ci)之外,Java在java.lang.reflect 包下新增了AnnotatedElement接(jie)(jie)口,該接(jie)(jie)口代表(biao)程(cheng)序(xu)中可以(yi)接(jie)(jie)受注(zhu)解的(de)程(cheng)序(xu)元素,該接(jie)(jie)口主要有(you)如(ru)下幾個實現(xian)類:

  Class:類(lei)定義(yi)
  Constructor:構造器定(ding)義
  Field:累的成員變量定義(yi)
  Method:類的(de)方法定義
  Package:類的包定義

  java.lang.reflect 包(bao)下(xia)主要包(bao)含(han)一些實(shi)現反射功能的(de)工具類,實(shi)際上,java.lang.reflect 包(bao)所有提供的(de)反射API擴充了讀取(qu)運行(xing)時(shi)(shi)Annotation信息的(de)能力。當(dang)一個Annotation類型被(bei)定(ding)義為運行(xing)時(shi)(shi)的(de)Annotation后,該注解才能是運行(xing)時(shi)(shi)可(ke)見(jian),當(dang)class文件被(bei)裝載時(shi)(shi)被(bei)保存在class文件中的(de)Annotation才會被(bei)虛擬機讀取(qu)。
  AnnotatedElement 接(jie)口是所有程序(xu)元素(Class、Method和(he)Constructor)的父接(jie)口,所以(yi)程序(xu)通過反射獲(huo)取了某個類(lei)的AnnotatedElement對(dui)象(xiang)之后,程序(xu)就可以(yi)調用該對(dui)象(xiang)的如下四個個方法來訪問Annotation信(xin)息:

  方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返(fan)回改程序元素上存(cun)在(zai)的、指定類(lei)型的注(zhu)解,如果該類(lei)型注(zhu)解不存(cun)在(zai),則返(fan)回null。
  方法(fa)2:Annotation[] getAnnotations():返回該(gai)程序元素上存在的所有注解(jie)。
  方法(fa)3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判斷該程序元素(su)上是否(fou)包含指定類(lei)型的注(zhu)解,存在(zai)則返(fan)回(hui)true,否(fou)則返(fan)回(hui)false.
  方法(fa)4:Annotation[] getDeclaredAnnotations():返回(hui)直(zhi)接存在(zai)于此(ci)(ci)元(yuan)素上的(de)(de)(de)(de)所有注釋。與此(ci)(ci)接口中的(de)(de)(de)(de)其他(ta)方法(fa)不同,該(gai)方法(fa)將忽(hu)略繼(ji)承的(de)(de)(de)(de)注釋。(如果(guo)沒有注釋直(zhi)接存在(zai)于此(ci)(ci)元(yuan)素上,則返回(hui)長度為零(ling)的(de)(de)(de)(de)一個數(shu)組(zu)。)該(gai)方法(fa)的(de)(de)(de)(de)調(diao)用(yong)者可以隨意修改返回(hui)的(de)(de)(de)(de)數(shu)組(zu);這不會對其他(ta)調(diao)用(yong)者返回(hui)的(de)(de)(de)(de)數(shu)組(zu)產生任何影(ying)響(xiang)。

  一個簡(jian)單的注解處理器:

/***********注解(jie)聲明***************/

/**
 * 水果名稱注解
 * @author peida
 *
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
    String value() default "";
}

/**
 * 水果顏色注解
 * @author peida
 *
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
    /**
     * 顏色枚舉
     * @author peida
     *
     */
    public enum Color{ BULE,RED,GREEN};
    
    /**
     * 顏色屬性(xing)
     * @return
     */
    Color fruitColor() default Color.GREEN;

}

/**
 * 水果(guo)供應者注解(jie)
 * @author peida
 *
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
    /**
     * 供(gong)應商(shang)編號
     * @return
     */
    public int id() default -1;
    
    /**
     * 供應商名稱
     * @return
     */
    public String name() default "";
    
    /**
     * 供(gong)應商地址
     * @return
     */
    public String address() default "";
}

/***********注(zhu)解使用***************/

public class Apple {
    
    @FruitName("Apple")
    private String appleName;
    
    @FruitColor(fruitColor=Color.RED)
    private String appleColor;
    
    @FruitProvider(id=1,name="陜西紅富士集團(tuan)",address="陜(shan)西省(sheng)西安市延安路89號紅富士大廈")
    private String appleProvider;
    
    public void setAppleColor(String appleColor) {
        this.appleColor = appleColor;
    }
    public String getAppleColor() {
        return appleColor;
    }
    
    public void setAppleName(String appleName) {
        this.appleName = appleName;
    }
    public String getAppleName() {
        return appleName;
    }
    
    public void setAppleProvider(String appleProvider) {
        this.appleProvider = appleProvider;
    }
    public String getAppleProvider() {
        return appleProvider;
    }
    
    public void displayName(){
        System.out.println("水果的(de)名字是:蘋果");
    }
}

/***********注解處理器***************/

public class FruitInfoUtil {
    public static void getFruitInfo(Class<?> clazz){
        
        String strFruitName=" 水果(guo)名稱(cheng):";
        String strFruitColor=" 水果顏色:";
        String strFruitProvicer="供應商(shang)信息:";
        
        Field[] fields = clazz.getDeclaredFields();
        
        for(Field field :fields){
            if(field.isAnnotationPresent(FruitName.class)){
                FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
                strFruitName=strFruitName+fruitName.value();
                System.out.println(strFruitName);
            }
            else if(field.isAnnotationPresent(FruitColor.class)){
                FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
                strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
                System.out.println(strFruitColor);
            }
            else if(field.isAnnotationPresent(FruitProvider.class)){
                FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
                strFruitProvicer=" 供應商(shang)編(bian)號:"+fruitProvider.id()+" 供應商名稱:"+fruitProvider.name()+" 供應(ying)商地址:"+fruitProvider.address();
                System.out.println(strFruitProvicer);
            }
        }
    }
}

/***********輸出(chu)結(jie)果***************/
public class FruitRun {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        FruitInfoUtil.getFruitInfo(Apple.class);
        
    }

}

====================================
 水(shui)果(guo)名稱:Apple
 水(shui)果(guo)顏色(se):RED
 供應商編(bian)號:1 供應商名稱:陜西紅富士集團 供應商地址:陜西省西安市延安路89號紅富士大廈

Java注(zhu)(zhu)解(jie)的基礎(chu)知(zhi)識點(見下(xia)面導(dao)圖(tu))基本都過(guo)了一(yi)(yi)遍,下(xia)一(yi)(yi)篇(pian)我(wo)們通過(guo)設計一(yi)(yi)個基于注(zhu)(zhu)解(jie)的簡單的ORM框(kuang)架,來(lai)綜合應用和進一(yi)(yi)步(bu)加(jia)深對注(zhu)(zhu)解(jie)的各個知(zhi)識點的理(li)解(jie)和運用。

 

 

參考:

深入理解Java:注解(Annotation)--注解處理器

 

 

posted @ 2014-09-16 11:23  ^_TONY_^  閱讀(11403)  評論(1)    收藏  舉報