<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      java基礎-注解Annotation原理和用法

      在很多java代碼中都可以看到諸如@Override、@Deprecated、@SuppressWarnings這樣的字符,這些就是注解Annotation。注解最早在jdk5中被引入,現在已經成為java平臺很重要的一部分了,很多的框架程序中也喜歡使用注解,如Spring、Mybatis等。

      那么,什么是注解呢?注解就是元數據,一種描述數據的數據,通俗一點就是為程序的元素(類、方法、成員變量)加上更直觀的說明,這些說明信息是與程序的業務邏輯無關的。但是,我們可以通過java的反射機制來獲取Annotation的信息,并根據這些信息來對程序進行賦值、分發等操作。
       
      java5.0定義了4個標準的meta-annotation元注解,它們被用來提供對其它annotation類型作說明,四種元注解如下:
      • @Target;
      • @Retention;
      • @Inherited;
      • @Documented;
       
      下面詳細說明這四種元注解的作用:
      @Target
      被用于描述注解的使用范圍,即注解可以用在所修飾對象的什么地方,取值可以是ElementType中的一種:
      • CONSTRUCTOR:用于描述構造器;
      • FIELD:用于描述域;
      • LOCAL_VARIABLE:用于描述局部變量;
      • METHOD:用于描述方法;
      • PACKAGE:用于描述包;
      • PARAMETER:用于描述參數;
      • TYPE:用于描述類、接口、注解類型或枚舉;
      @Target(ElementType.TYPE)
      public @interface Exculde{
          /**
          * 名稱,默認值為""
          * @return
          */
          public String name() default "";
      }
       
      @Target(ElementType.FIELD)
      public @interface Inject{
          /**
          * id,默認值為""
          * @return
          */
          public String id() default "";
       
          /**
          * 類,默認值為""
          * @return
          */
          public Class clazz() default Object.class;
           
      }
      上面定義了兩個注解,注解@Exculde只能用于修飾類、接口、注解、枚舉,注解@Inject只能修飾類型的域,如:
      @Exculde(name="admin")
      public class User{
           @Inject(id="username",clazz=String.class)
           private String username;
      }
       
      @Retention
      用于描述注解的生命周期,即注解能在源碼到JVM裝載過程中的哪一個級別上有效。有些annotation僅出現在源碼中,被編譯器丟棄;有些annotation能被編譯進class文件中,可能被JVM忽略;有些annotation不但能夠被編譯進class文件,而且能夠在class文件被裝載時被讀取。這三種情況對應RetentionPoicy的三種取值:
      • SOURCE:源碼文件中保留;
      • CLASS:class文件中保留;
      • RUNTIME:運行時保留;
       
      @Inherited
      用于描述注解是可以被繼承的,如果一個使用了@Inherited修飾的annotation被用于一個class,那么這個annotation也將被用于這個class的子類。@Inherited是一個標記注解,沒有參數選項,它修飾的annotation是被標記的class的子類所繼承,類并不從它所實現的接口繼承annotation,方法并不從它所重載的方法繼承annotation。
           當使用java的反射去獲取一個@Inherited修飾的annotation時,反射檢查將遞歸檢查,檢查class和其父類,直到發現指定的annotation類型被發現,或者到達類繼承結構的頂層。
       
      @Documented
          用于描述注解信息應該被作為被標注的程序的公共API,即應該把注解信息保留文檔中。@Documented也是一個標記注解,沒有參數選項。
      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      @Inherited
      @Documented
      public @interface Exculde{
          /**
          * 名稱注解,默認值為""
          * @return
          */
          public String name() default "";
      }
      如果你看過了上面的元注解,如果還不能理解也沒關系,下面我們通過自定義注解來進一步理解元注解。
       
      自定義注解需要使用@interface,類似于定義一個類使用class,但定義注解時不能再繼承其它的類或者接口,它已經自動繼承了java.lang.annotation.Annotation接口。@interface用來聲明一個注解,其中的每一個方法實際上聲明了一個配置參數,方法的名稱就是參數的名稱,方法的返回值類型就是參數的類型,也可以使用default來聲明參數的默認值。
       
      定義注解的格式如下:
      public @interface 注解名{ 定義體 }
       
      注解參數可支持的數據類型如下:
      • 基本類型;
      • Class;
      • String;
      • Enum;
      • Annotation;
      • 以上所有類型的數組形式;
      下面定義一個類似于Spring的注解,用于向實例對象注入屬性的值:
      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Inject{
          /**
          * ID,默認值為""
          * @return
          */
          public String id() default "";
       
          /**
          * 類,默認值為""
          * @return
          */
          public Class clazz() default Object.class;
       
      }
      把@Inject標注在類UserAction的屬性上:
      public class UserAction {
           @Inject(id="userService",clazz=UserService.class)
           private UserService userService;
      }
      在IOC容器框架中,對象都會被自動初始化,如果我們要實現IOC的這種功能,我們應該為加上@Inject注解的屬性userService注入它的值。首先我們應該通過反射獲取userService的域對象field,通過field獲取@Inject注解的信息,然后根據注解的id和clazz得到它依賴的值:
       
      Inject inject = field.getAnnotation(Inject.class);
      String id = inject.id();
      Class clazz = inject.clazz();
       
      Object userService = Class.forName(clazz.getName).newInstance();
      field.setAccessible(true);
      field.set(object,userService);
      上面代碼中,調用field.getAnnotation(Inject.class)獲取到@Inject的對象,然后獲取@Inject的id和clazz值,通過反射實例化clazz的對象,再反射賦值給field。這就是Spring那些框架的依賴注入的實現原理,有興趣的可以自己再優化一下。
       
      讀取類的注解信息還有其它的幾個方法,在此不再一一說明,可以自行研究java.lang.reflect包。經過上面的說明,由此我們也可以知道注解僅僅是一種元數據,增強類、屬性、參數的描述,使用注解的關鍵在于獲取注解的信息,再通過反射的手段來實現注解想達成的功能。
       
       
       
      文章同步發布在朗度云網站,傳送門:
      posted @ 2016-08-14 06:30  朗度云  閱讀(419)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 骚虎视频在线观看| 全部免费毛片在线播放| 亚洲中文字幕av天堂| 内射囯产旡码丰满少妇| 高清美女视频一区二区三区| 亚洲av永久无码精品网站| 亚洲成av人片在www鸭子| 欧美牲交a欧美牲交aⅴ图片| 日日噜久久人妻一区二区| 人妻中文字幕亚洲一区| 波多野结系列18部无码观看AV| 国产精品国产三级国av| 天天综合天天添夜夜添狠狠添| √新版天堂资源在线资源| 特黄少妇60分钟在线观看播放| 久久综合给合久久狠狠狠| 沛县| 国产精品福利片在线观看| 国产成人精彩在线视频| 天天拍夜夜添久久精品大| 麻豆精产国品一二三区区| 亚洲欧洲∨国产一区二区三区 | 视频网站在线观看不卡| 久久精品国产精品亚洲综合| 丰满人妻被黑人猛烈进入| 国产精品男女爽免费视频| 99久久亚洲综合精品成人网| 67194熟妇在线观看线路| 插入中文字幕在线一区二区三区| 性少妇tubevⅰdeos高清| 国产一区二区不卡在线视频| 欧美丰满熟妇xxxx性大屁股| 日韩精品二区三区四区| 国产永久免费高清在线观看| 婷婷久久香蕉五月综合加勒比| 亚洲老熟女一区二区三区| 五月婷久久麻豆国产| 中文字幕日韩有码第一页| 欧美乱大交aaaa片if| 色综合天天综合天天更新| 国产av国片精品一区二区|