Nomad & His Life

          博觀而約取,厚積而薄發(fā)
          posts - 15, comments - 88, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          Java反射經(jīng)典實例 Java Reflection Cookbook (初級)

          Posted on 2006-08-24 10:52 Nomad 閱讀(7389) 評論(10)  編輯  收藏 所屬分類: Java
          Java提供了一套機制來動態(tài)執(zhí)行方法和構造方法,以及數(shù)組操作等,這套機制就叫——反射。反射機制是如今很多流行框架的實現(xiàn)基礎,其中包括Spring、Hibernate等。原理性的問題不是本文的重點,接下來讓我們在實例中學習這套精彩的機制。

          1. 得到某個對象的屬性

          1?public?Object?getProperty(Object?owner,?String?fieldName)?throws?Exception?{
          2?????Class?ownerClass?=?owner.getClass();
          3?
          4?????Field?field?=?ownerClass.getField(fieldName);
          5?
          6?????Object?property?=?field.get(owner);
          7?
          8?????return?property;
          9?}

          Class ownerClass = owner.getClass():得到該對象的Class。

          Field field = ownerClass.getField(fieldName):通過Class得到類聲明的屬性。

          Object property = field.get(owner):通過對象得到該屬性的實例,如果這個屬性是非公有的,這里會報IllegalAccessException。



          2. 得到某個類的靜態(tài)屬性

          ?1?public?Object?getStaticProperty(String?className,?String?fieldName)
          ?2?????????????throws?Exception?{
          ?3?????Class?ownerClass?=?Class.forName(className);
          ?4?
          ?5?????Field?field?=?ownerClass.getField(fieldName);
          ?6?
          ?7?????Object?property?=?field.get(ownerClass);
          ?8?
          ?9?????return?property;
          10?}


          Class ownerClass = Class.forName(className) :首先得到這個類的Class。

          Field field = ownerClass.getField(fieldName):和上面一樣,通過Class得到類聲明的屬性。

          Object property = field.get(ownerClass) :這里和上面有些不同,因為該屬性是靜態(tài)的,所以直接從類的Class里取。


          3. 執(zhí)行某對象的方法

          ?1?public?Object?invokeMethod(Object?owner,?String?methodName,?Object[]?args)?throws?Exception?{
          ?2?
          ?3?????Class?ownerClass?=?owner.getClass();
          ?4?
          ?5?????Class[]?argsClass?=?new?Class[args.length];
          ?6?
          ?7?????for?(int?i?=?0,?j?=?args.length;?i?<?j;?i++)?{
          ?8?????????argsClass[i]?=?args[i].getClass();
          ?9?????}
          10?
          11?????Method?method?=?ownerClass.getMethod(methodName,?argsClass);
          12?
          13?????return?method.invoke(owner,?args);
          14?}

          Class owner_class = owner.getClass() :首先還是必須得到這個對象的Class。

          5~9行:配置參數(shù)的Class數(shù)組,作為尋找Method的條件。

          Method method = ownerClass.getMethod(methodName, argsClass):通過Method名和參數(shù)的Class數(shù)組得到要執(zhí)行的Method。

          method.invoke(owner, args):執(zhí)行該Method,invoke方法的參數(shù)是執(zhí)行這個方法的對象,和參數(shù)數(shù)組。返回值是Object,也既是該方法的返回值。


          4. 執(zhí)行某個類的靜態(tài)方法

          ?1?public?Object?invokeStaticMethod(String?className,?String?methodName,
          ?2?????????????Object[]?args)?throws?Exception?{
          ?3?????Class?ownerClass?=?Class.forName(className);
          ?4?
          ?5?????Class[]?argsClass?=?new?Class[args.length];
          ?6?
          ?7?????for?(int?i?=?0,?j?=?args.length;?i?<?j;?i++)?{
          ?8?????????argsClass[i]?=?args[i].getClass();
          ?9?????}
          10?
          11?????Method?method?=?ownerClass.getMethod(methodName,?argsClass);
          12?
          13?????return?method.invoke(null,?args);
          14?}


          基本的原理和實例3相同,不同點是最后一行,invoke的一個參數(shù)是null,因為這是靜態(tài)方法,不需要借助實例運行。



          5. 新建實例
          ?1?
          ?2?public?Object?newInstance(String?className,?Object[]?args)?throws?Exception?{
          ?3?????Class?newoneClass?=?Class.forName(className);
          ?4?
          ?5?????Class[]?argsClass?=?new?Class[args.length];
          ?6?
          ?7?????for?(int?i?=?0,?j?=?args.length;?i?<?j;?i++)?{
          ?8?????????argsClass[i]?=?args[i].getClass();
          ?9?????}
          10?
          11?????Constructor?cons?=?newoneClass.getConstructor(argsClass);
          12?
          13?????return?cons.newInstance(args);
          14?
          15?}


          這里說的方法是執(zhí)行帶參數(shù)的構造函數(shù)來新建實例的方法。如果不需要參數(shù),可以直接使用newoneClass.newInstance()來實現(xiàn)。

          Class newoneClass = Class.forName(className):第一步,得到要構造的實例的Class。

          第5~第9行:得到參數(shù)的Class數(shù)組。

          Constructor cons = newoneClass.getConstructor(argsClass):得到構造子。

          cons.newInstance(args):新建實例。


          6. 判斷是否為某個類的實例

          1?public?boolean?isInstance(Object?obj,?Class?cls)?{
          2?????return?cls.isInstance(obj);
          3?}



          7. 得到數(shù)組中的某個元素
          1?public?Object?getByArray(Object?array,?int?index)?{
          2?????return?Array.get(array,index);
          3?}



          附完整源碼:

          import?java.lang.reflect.Array;
          import?java.lang.reflect.Constructor;
          import?java.lang.reflect.Field;
          import?java.lang.reflect.Method;


          /**
          ?*?Java?Reflection?Cookbook
          ?*
          ?*?
          @author?Michael?Lee
          ?*?
          @since?2006-8-23
          ?*?
          @version?0.1a
          ?
          */

          public?class?Reflection?{
          ????
          /**
          ?????*?得到某個對象的公共屬性
          ?????*
          ?????*?
          @param?owner,?fieldName
          ?????*?
          @return?該屬性對象
          ?????*?
          @throws?Exception
          ?????*
          ?????
          */
          ????
          public?Object?getProperty(Object?owner,?String?fieldName)?throws?Exception?{
          ????????Class?ownerClass?
          =?owner.getClass();

          ????????Field?field?
          =?ownerClass.getField(fieldName);

          ????????Object?property?
          =?field.get(owner);

          ????????
          return?property;
          ????}

          ????
          /**
          ?????*?得到某類的靜態(tài)公共屬性
          ?????*
          ?????*?
          @param?className???類名
          ?????*?
          @param?fieldName???屬性名
          ?????*?
          @return?該屬性對象
          ?????*?
          @throws?Exception
          ?????
          */
          ????
          public?Object?getStaticProperty(String?className,?String?fieldName)
          ????????????
          throws?Exception?{
          ????????Class?ownerClass?
          =?Class.forName(className);

          ????????Field?field?
          =?ownerClass.getField(fieldName);

          ????????Object?property?
          =?field.get(ownerClass);

          ????????
          return?property;
          ????}


          ????
          /**
          ?????*?執(zhí)行某對象方法
          ?????*
          ?????*?
          @param?owner
          ?????*????????????對象
          ?????*?
          @param?methodName
          ?????*????????????方法名
          ?????*?
          @param?args
          ?????*????????????參數(shù)
          ?????*?
          @return?方法返回值
          ?????*?
          @throws?Exception
          ?????
          */
          ????
          public?Object?invokeMethod(Object?owner,?String?methodName,?Object[]?args)
          ????????????
          throws?Exception?{

          ????????Class?ownerClass?
          =?owner.getClass();

          ????????Class[]?argsClass?
          =?new?Class[args.length];

          ????????
          for?(int?i?=?0,?j?=?args.length;?i?<?j;?i++)?{
          ????????????argsClass[i]?
          =?args[i].getClass();
          ????????}

          ????????Method?method?
          =?ownerClass.getMethod(methodName,?argsClass);

          ????????
          return?method.invoke(owner,?args);
          ????}


          ??????
          /**
          ?????*?執(zhí)行某類的靜態(tài)方法
          ?????*
          ?????*?
          @param?className
          ?????*????????????類名
          ?????*?
          @param?methodName
          ?????*????????????方法名
          ?????*?
          @param?args
          ?????*????????????參數(shù)數(shù)組
          ?????*?
          @return?執(zhí)行方法返回的結果
          ?????*?
          @throws?Exception
          ?????
          */
          ????
          public?Object?invokeStaticMethod(String?className,?String?methodName,
          ????????????Object[]?args)?
          throws?Exception?{
          ????????Class?ownerClass?
          =?Class.forName(className);

          ????????Class[]?argsClass?
          =?new?Class[args.length];

          ????????
          for?(int?i?=?0,?j?=?args.length;?i?<?j;?i++)?{
          ????????????argsClass[i]?
          =?args[i].getClass();
          ????????}

          ????????Method?method?
          =?ownerClass.getMethod(methodName,?argsClass);

          ????????
          return?method.invoke(null,?args);
          ????}



          ????
          /**
          ?????*?新建實例
          ?????*
          ?????*?
          @param?className
          ?????*????????????類名
          ?????*?
          @param?args
          ?????*????????????構造函數(shù)的參數(shù)
          ?????*?
          @return?新建的實例
          ?????*?
          @throws?Exception
          ?????
          */
          ????
          public?Object?newInstance(String?className,?Object[]?args)?throws?Exception?{
          ????????Class?newoneClass?
          =?Class.forName(className);

          ????????Class[]?argsClass?
          =?new?Class[args.length];

          ????????
          for?(int?i?=?0,?j?=?args.length;?i?<?j;?i++)?{
          ????????????argsClass[i]?
          =?args[i].getClass();
          ????????}

          ????????Constructor?cons?
          =?newoneClass.getConstructor(argsClass);

          ????????
          return?cons.newInstance(args);

          ????}


          ????
          ????
          /**
          ?????*?是不是某個類的實例
          ?????*?
          @param?obj?實例
          ?????*?
          @param?cls?類
          ?????*?
          @return?如果?obj?是此類的實例,則返回?true
          ?????
          */
          ????
          public?boolean?isInstance(Object?obj,?Class?cls)?{
          ????????
          return?cls.isInstance(obj);
          ????}
          ????
          ????
          /**
          ?????*?得到數(shù)組中的某個元素
          ?????*?
          @param?array?數(shù)組
          ?????*?
          @param?index?索引
          ?????*?
          @return?返回指定數(shù)組對象中索引組件的值
          ?????
          */
          ????
          public?Object?getByArray(Object?array,?int?index)?{
          ????????
          return?Array.get(array,index);
          ????}
          }


          評論

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2007-02-26 16:46 by kl;kl;
          k;kl;

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2007-02-26 16:46 by kl;kl;
          ft

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2007-02-26 16:47 by kl;kl;
          sdf

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2007-05-18 17:05 by zhanglm
          收益非淺,thank you

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)[未登錄]  回復  更多評論   

          2007-07-09 16:35 by Gavin
          轉(zhuǎn)了你的這篇文章,非常感謝!做個鏈接吧!www.javaflag.com

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2007-11-12 14:08 by 捕風
          很精辟!

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2007-12-12 13:18 by ZZW
          寫得很棒,太感謝你了

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2009-02-10 17:34 by 游客
          很好很強大!

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2010-01-27 20:37 by libis
          分享了哈...thx

          # re: Java反射經(jīng)典實例 Java Reflection Cookbook (初級)  回復  更多評論   

          2011-12-06 14:33 by 游客
          謝謝,學習了
          主站蜘蛛池模板: 铁岭县| 南和县| 阿合奇县| 岑溪市| 咸宁市| 嵊州市| 台湾省| 北票市| 巴东县| 兴化市| 阳山县| 和硕县| 扬中市| 屏南县| 华宁县| 龙里县| 迭部县| 微山县| 肇源县| 天长市| 文水县| 石景山区| 汉阴县| 汉寿县| 灌阳县| 天长市| 嘉峪关市| 南阳市| 丽水市| 花莲市| 宜章县| 河西区| 信丰县| 刚察县| 铅山县| 浦北县| 永定县| 韩城市| 盐山县| 曲阜市| 阳朔县|