posts - 262,  comments - 221,  trackbacks - 0
          【1】Method類簡介
          Java反射技術的一個基本應用之一就是在運行時期間動態地調用方法。要動態地調用方法,首先要獲得方法本身。步驟如下:
            1.獲得Class對象
            2.調用Class對象的getMethod(String, Class[])方法獲得指定的方法
           
          getMethod方法的第一個參數用來指定方法的名稱,第二個參數是一個Class數組,用來存放代表各個參數類型的Class對象。這個方法有一個值得注意的地方:
           
          如果參數類型是原子類型(int,long,short等),要使用諸如int.class,long.class來獲取其對應Class對象,而不能使用對應的封裝類對象。
           
          在獲得Method對象之后,就可以在運行時動態地調用方法了。Method類里面最主要的方法有以下幾種
            1.獲取方法所在的類:                     getDeclaringClass()
            2.獲取方法簽名中所有聲明的拋出異常:getExceptionTypes()
            3.獲取方法簽名中所有參數的類型:     getParameterTypes()
            4.獲取方法簽名中返回值的類型:        getReturnType()
            5.調用方法:                               Object invoke(Object obj, Object... args)
           
          Method類的核心就是invoke方法,該方法用于Method對象喚起對象中對應的方法,特別要注意的是第二個參數:通常這是一個Object數組,這意味著如果參數是原子類型數據,必須先把他轉換成對應的封裝類對象,invoke方法會在后臺自動將其解壓成原子類型。
           
          從JDK1.5開始之后,增加了"自動裝箱"和"自動開箱"的功能,所以你可以看到在行61處,使用了原子類型數據而非封裝類來傳遞參數。如果是在JDK1.4或以下版本,則此處會報錯。建議不采用此種做法,以免出現數據類型完全的問題。


          【2】使用反射拷貝對象的思路
           1. 獲取源對象的所有成員變量列表

           2. 每次取出變量列表中的一個變量,獲取其getXxx()和setXxx(Type)方法名稱

           3. 根據getXxx()和setXxx(Type)方法名稱獲得對應的Method對象

           4. 源對象通過invoke(Object, Class[])方法調用getXxx()方法,獲得成員變量的值

           5. 目標對象通過invoke(Object, Class[])的方法的setXxx(Type)方法,為目標對象的成員變量賦值
            
          其中關鍵的代碼段格式如下:

           1. 創建Method對象:Class.getMethod(method name, method prameters class array)

           2. 調用方法:method.invoke(object, method parameters class array)


          【3】示例代碼
                  // 獲得對象的所有屬性
                  Field fields[] = classType.getDeclaredFields();

                  
          for (int i = 0; i < fields.length; i++) {
                      Field field 
          = fields[i];

                      String fieldName 
          = field.getName();
                      String firstLetter 
          = fieldName.substring(01).toUpperCase();

                      
          // 獲得和屬性對應的getXXX()方法的名字
                      String getMethodName = "get" + firstLetter + fieldName.substring(1);
                      
          // 獲得和屬性對應的setXXX()方法的名字
                      String setMethodName = "set" + firstLetter + fieldName.substring(1);

                      
          // 獲得和屬性對應的getXXX()方法
                      Method getMethod = classType.getMethod(getMethodName,
                              new Class[] {});
                      
          // 獲得和屬性對應的setXXX()方法,使用filed對象的類型
                      Method setMethod = classType.getMethod(setMethodName,
                              
          new Class[] { field.getType() });

                      
          // 調用原對象的getXXX()方法:指定調用的對象和方法的參數值列表
                      Object value = getMethod.invoke(object, new Object[] {});
                      System.out.println(fieldName 
          + ":" + value);
                      
          // 調用拷貝對象的setXXX()方法:指定調用的對象和參數值列表(注意必須是Object類型)
                      setMethod.invoke(objectCopy, new Object[] { value });
                  }


          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2008-09-03 16:05 Paul Lin 閱讀(1831) 評論(0)  編輯  收藏 所屬分類: J2SE
          <2008年9月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 衡南县| 安泽县| 桂林市| 塘沽区| 沽源县| 绥宁县| 许昌县| 石河子市| 建德市| 安阳市| 金乡县| 剑川县| 泽州县| 井研县| 奈曼旗| 桦南县| 清水河县| 长子县| 本溪市| 扎鲁特旗| 岳普湖县| 横山县| 陆河县| 修水县| 长治县| 涿鹿县| 雷州市| 江山市| 玛纳斯县| 玛多县| 宁南县| 枣庄市| 阜城县| 县级市| 抚松县| 阳原县| 盐山县| 鹤壁市| 泰安市| 廉江市| 原阳县|