反射內省JaveBean與簡單工廠設計模式 – JAVA編程語言程序開發技術文章

 java中一個強大的功能,莫過於反射瞭。通常我們看看的Struct2、Struct1、Spring、Hibernate等等集合無一不使用瞭反射機制。那麼什麼是反射呢,到底有什麼用呢?
一、反射機制概念
   簡單的講,反射就是通過把指定的類中各種元素成分都映射成相關的反射包中的相應類,使得我們可以動態的調用類的相應成員,比如構造方法、成員方法、成員變量等。它被視為動態(或準動態)語言的一個關鍵性質。這個機制允許程序在運行時透過Reflection APIs取得任何一個已知名稱的class的內部信息,包括其modifiers(諸如public, static 等)、superclass(例如Object)、實現之interfaces(例如Cloneable),也包括fields和methods的所有信息,並可於運行時改變fields內容或喚起methods。
Java反射機制容許程序在運行時加載、探知、使用編譯期間完全未知的classes。
換言之,Java可以加載一個運行時才得知名稱的class,獲得其完整結構。
二、反射的功能:
2.1在運行時判斷任意一個對象所屬的類  如 aclass.getClass() == bclass.getClass()
2.2在運行時構造任意一個類的對象    如Class.forName(className).netInstance(),className是運行時才得出來的類名
2.3在運行時判段任意一個類所具有的成員變量和方法 
2.4在運行時調用任一個對象的方法
2.5在運行時創建新類對象
三、反射API中重點的幾個類
Class:Class 類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,註釋是一種接口。每個數組屬於被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該Class 對象
      沒有構造方法,具體如何獲取Class對象的實例,下面的示例代碼中將會總結。
      常用的方法用:
         T cast(Object obj) 、static Class<?> forName(String className) 、 ClassLoader getClassLoader() 、 Constructor<T> getConstructor(Class<?>… parameterTypes) 、
         Constructor<?>[] getConstructors() 、  Constructor<T> getDeclaredConstructor(Class<?>… parameterTypes)、 Constructor<?>[] getDeclaredConstructors() 、
         Field getDeclaredField(String name)、 Field[] getDeclaredFields() 、Method getDeclaredMethod(String name, Class<?>… parameterTypes)
         Method[] getDeclaredMethods() 、Field getField(String name) 、 Field[] getFields() 、 Method getMethod(String name, Class<?>… parameterTypes)
         Method[] getMethods() 、int getModifiers() 、String getName() 、InputStream getResourceAsStream(String name)、 boolean isArray() 、T newInstance()
Constructor:Constructor 提供關於類的單個構造方法的信息以及對它的訪問權限
     沒用構造方法,一般都是通過Class對象中的相應類來獲得Constructor對象的。
      常用的方法:
        Class<T> getDeclaringClass() 、Class<?>[] getExceptionTypes() 、Type[] getGenericExceptionTypes()、Type[] getGenericParameterTypes() 、
         int getModifiers() 、String getName() 、Class<?>[] getParameterTypes() 、boolean isVarArgs() 、 T newInstance(Object… initargs)
Method:Method 提供關於類或接口上單獨某個方法(以及如何訪問該方法)的信息。所反映的方法可能是類方法或實例方法(包括抽象方法)。
        沒有構造方法,也是通常Class對象中相應的方法來獲取Method對象。
        常用的方法:
          Class<?> getDeclaringClass() 、int getModifiers() 、String getName() 、Class<?>[] getParameterTypes()
           Class<?> getReturnType() 、Object invoke(Object obj, Object… args)
Field:Field提供有關類或接口的單個字段的信息,以及對它的動態訪問權限。反射的字段可能是一個類(靜態)字段或實例字段。
         沒有構造方法,也是通常Class對象中相應的方法來獲取Method對象。
        常用的方法:
         Object get(Object obj) 、 int getModifiers() 、String getName() 、Class<?> getType() 、 void set(Object obj, Object value)。另外還支持相應的int getInt(Object obj)
         與void setInt(Object obj, int value)等相應的直接對基本數據類型進行操作。
Modifier:Modifier 類提供瞭static 方法和常量,對類和成員訪問修飾符進行解碼。
          這是沒有構造方法的,都是通過相應的Class、Constructor、Method、Field類對象得到的,且常用的方法static boolean isPublic(int mod) 、static boolean isPrivate(int mod) 等,用個方法是static String toString(int mod)蠻好用的,此方法是返回描述指定修飾符中的訪問修飾符標志的字符串。
四、反射舉例代碼:
在使用Java的反射功能時,基本首先都要獲取類的Class對象,再通過Class對象獲取其他的對象
[java] 
package com.enhance; 
import java.lang.reflect.Constructor; 
import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
  
public class ReflectDemo { 
     
    private int pos ; 
    public String name; 
     
    private int size ; 
    private final static double PI = 3.1415926; 
     
    private ArrayList<String> alist = new ArrayList<String>(); 
     
    /**
     * 靜態方法,反射調用invork時,第一個參數為null即無作用對象,由於也沒有參數。
     * 所以最終的反射在調用時,肯定是invork(null)即可。
     * @return
     */ 
    public static double getPI(){ 
        return PI; 
    } 
  
    /**
     * @param args
     * @throws Exception 
     */ 
    public static void main(String[] args) throws Exception { 
        getClassTest(); 
        applyReflectChangeObjValDemo(); 
        reflectInvorkArrayDeom(); 
        //獲取一個類的方法簽名、構造函數簽名、成員變量等。 
        printClass("java.lang.String"); 
        arraysAsListTest(); 
         
    } 
     
    public static void getClassTest() throws Exception{ 
         
        /*
        三種方式來獲得Class對象,三種方式得出來的對象都是一個都是此類的字節碼對象
        1> 對象.getClass()
        2> 類名.class     不會加載類,即不會靜態初始化等
        3> Class.forName(完全限定類名)   會加載類,會靜態初始化
         */ 
         
        String str1 = "abc"; 
        Class c1 = str1.getClass(); 
        Class c2 = String.class; 
        Class c3 = Class.forName("java.lang.String"); 
         
        System.out.println("c1==c2::"+(c1==c2));  // true 
        System.out.println("c2==c3::"+(c2==c3));  // true 
         
        //Class對象中用isPrimitive()方法可判斷是否基本類型字節碼 
        System.out.println("c1.isPrimitive()=="+c1.isPrimitive()); //false 
         
        Class c4 = int.class; 
        System.out.println("c1.isPrimitive()=="+c4.isPrimitive()); // true 
        System.out.println("c3==c4::"+(c3==c4));  // false   
        //包裝類,可使用類名.TYPE得到基本類型的Class對象 
        Class c5 = Integer.TYPE; 
        System.out.println("c4==c5::"+(c4==c5));  // true 
         
         
        //反射得到實例對象的,有兩個方法一種是先得到反射中的構造器,通過構造器的newInstance來搞定 
        //另一種是直接通過class的newInstance,但這個方法是要求類必須有個無參的構造方法 
        Class strCl = Class.forName("java.lang.String"); 
        Constructor strCon = strCl.getConstructor(StringBuilder.class); 
        String str = (String)strCon.newInstance(new StringBuilder("sdf")); 
        String strr = (String)strCl.newInstance(); 
         
    } 
     
    private static void arraysAsListTest() { 
        int[] a1 = new int[]{4,5,6}; 
        List l1 = Arrays.asList(a1);  //因為a1不是object[]數組,不會用jdk1.4中的asList(Object[] objs)來調用 
                                      //而是用jdk1.5中的asList(T… args)所以int[]當成瞭一個Object來傳入,此 
                                      //此List中隻有一個元素,是int[]型的 Object。 
        System.out.println(l1+"———–"+l1.size()); //size為1,隻有一個元素  打印的是:[[I@10b30a7]———–1 
        for(int i=0;i<l1.size();i++){ 
             
            System.out.print(l1.get(i)+" ,"); //[I@c17164 隻有此元素 
        } 
    } 
  
    /*
     * 總結:反射在調用帶數組參數的方法時,一定要註意invork方法調用的情況,因為傳入invork方法是一個數組的話,編譯器會采用JDK1.4折方法特性將數組拆包,
     * 數組中每個元素將作為一個參數傳入到相應方法中。這樣肯定會與之前的getMethod中的數組.class有沖突,會報
     * java.lang.IllegalArgumentException: wrong number of arguments 參數數量不對瞭。
     * 為瞭解決此問題,有兩種方法,一種是不讓JDK1.4插手,那麼就可將數組前面強轉成Object,這樣編譯器會使用JDK1.5的,不會將數組拆包。
     * 如:m1.invoke(rd, (Object)new String[]{"abc","bcd"});
     * 另一種方法是,還是讓JDK1.4編,那麼外面再用一個數組包起,這個數組。這樣JDK1.4遇到這個數組的數組,拆包後還是一樣數組正好與getMethod中是一致的。
     * 如m1.invoke(rd, new Object[]{new String[]{"abc","bcd"}});
     * 
     * */ 
    private static void reflectInvorkArrayDeom() { 
        ReflectDemo rd = new ReflectDemo(); 
         
        Method m1 = null ; 
        try{ 
            Class lc = rd.getClass(); 
            int[] intArr = new int[]{3,5}; 
            m1 = lc.getMethod("printIntArray", int[].class); 
            m1.invoke(rd, intArr); 
             
            String[] strArr = new String[]{"abc","bcd"}; 
            m1 = lc.getMethod("printStringArray", String[].class); 
            //m1.invoke(rd, strArr); //這樣調用是有問題的,因為在invork方法發現第二個參數是String[]數組 
                                //此時invork會用1.4的Object[],在1.4中第二個參數會先被拆包,拆成多個參數傳與相應的方法中 
                                //但此時已經與getMethod中聲明的String[].class有沖突瞭,所以會報IllegalArgumentException異常 
                                //java.lang.IllegalArgumentException: wrong number of arguments 參數數量不對 
            //解決這個問題有兩個方法,一是用jdk1.5提供的可變參數,那麼為讓編譯器知道去調用1.5的,那麼就要將數組變成一個對象。 
            m1.invoke(rd, (Object)strArr); 
            //另一個解決方法是,1.4的是不要個數組嗎,給個數組它new Object[],這個數組裡呢,再傳入個String[]數組,這樣編譯器在使用1.4的時 
            //先將數組拆包後,取去其中元素,正好是一個數組與上面的String[].class是吻合的。即可以調用瞭。 
            m1.invoke(rd, new Object[]{strArr}); 
             
             
            Integer[] integerArr = new Integer[]{12,56}; 
            m1 = lc.getMethod("printIntegerArray", Integer[].class); 
            //m1.invoke(rd, integerArr);  同時這樣調用也是有問題的 
            m1.invoke(rd, (Object)integerArr); 
        }catch(Exception e){ 
            e.printStackTrace(); 
        } 
         
    } 
  
    /**
     * printClass用於打印,運行時才知道來的類,具體哪些構造方法,哪些方法以及哪些變量
     * @param className
     */ 
    private static void printClass(String className) { 
        ArrayList<String> al = new ArrayList<String>();  
        Class clazz = null ; 
        try { 
            clazz = Class.forName(className); 
        } catch (ClassNotFoundException e) { 
            throw new RuntimeException("類名有問題,請重新輸入"); 
             
        } 
        String modifierName = Modifier.toString(clazz.getModifiers()); 
        StringBuilder sb = new StringBuilder(); 
        if(modifierName != null && modifierName.length()>0){ 
            sb.append(modifierName); 
        } 
         
        sb.append(" "+clazz.getName()+"{"); 
        sb.append(System.getProperty("line.separator")); 
        printConstructors(clazz,sb); 
        printMethods(clazz,sb); 
        printFields(clazz,sb); 
         
        sb.append(System.getProperty("line.separator")); 
        sb.append("}"); 
        System.out.println(sb.toString()); 
    } 
  
    /**
     * 打印運行時類的,變量。
     * @param clazz 運行時類的字節碼
     * @param sb 打印的內容先用StringBuilder緩存下
     */ 
    private static void printFields(Class clazz, StringBuilder sb) { 
        sb.append(System.getProperty("line.separator")); 
        sb.append("\t"); 
        Field[] fields = clazz.getFields(); 
        for(Field field:fields){ 
            sb.append(Modifier.toString(field.getModifiers())); 
            sb.append(field.getName()); 
            sb.append(System.getProperty("line.separator")); 
            sb.append("\t"); 
        } 
    } 
  
    /**
     * 打印運行時類的方法。
     * @param clazz 運行時類的字節碼
     * @param sb 打印的內容先用StringBuilder緩存下
     */ 
    private static void printMethods(Class clazz, StringBuilder sb) { 
        sb.append(System.getProperty("line.separator")); 
        sb.append("\t"); 
        Method[] methods = clazz.getMethods(); 
        for(Method method:methods){ 
            Class[] paraClasses = method.getParameterTypes(); 
            sb.append(Modifier.toString(method.getModifiers())); 
            sb.append(" "+method.getName()+"("); 
            for(Class paraClass: paraClasses){ 
                sb.append(paraClass.getName()+","); 
            } 
            if(null != paraClasses && 0 != paraClasses.length){ 
                sb.deleteCharAt(sb.length()-1); 
            } 
            sb.append(")"); 
            sb.append(System.getProperty("line.separator")); 
            sb.append("\t"); 
        } 
    } 
  
    /**
     * 打印運行時類的構造方法。
     * @param clazz 運行時類的字節碼
     * @param sb 打印的內容先用StringBuilder緩存下
     */ 
    private static void printConstructors(Class clazz,StringBuilder sb) { 
        sb.append("\t"); 
        Constructor[] cons = clazz.getConstructors(); 
        for(Constructor con : cons){ 
            String conModifier = Modifier.toString(con.getModifiers()); 
            sb.append(conModifier); 
            sb.append(" "+con.getName()+"("); 
            Class[] types = con.getParameterTypes(); 
            for(Class type:types){ 
                sb.append(type.getName()+","); 
            } 
            if(null!=types && 0 !=types.length){ 
                sb.deleteCharAt(sb.length()-1); //刪除最後一個逗號,字符 
            } 
            sb.append(")"); 
            sb.append(System.getProperty("line.separator")); 
            sb.append("\t"); 
        } 
    } 
  
  
    /**
     * 測試反射運行時得到的方法及變量,如何調用,如何設置值。
     */ 
    private static void applyReflectChangeObjValDemo() { 
        ReflectDemo rd = new ReflectDemo(); 
     
        Method m1 = null ; 
        try{ 
            Class lc = rd.getClass(); 
            m1 = lc.getMethod("setName", String.class);  //setName方法,有參數參數是String的。 
            Boolean b = (Boolean)m1.invoke(rd, "four"); 
            System.out.println("—————:"+rd.getName()); 
            rd.setSize(21); 
            m1 = lc.getMethod("getSize"); 
            Integer size = (Integer)m1.invoke(rd); //getSize方法返回int,沒有參數。 
            System.out.println("Size大小::"+size); 
             
            m1 = lc.getMethod("getPI"); 
            Double d = (Double)m1.invoke(null); //靜態方法,無參數且返回為double,靜態方法第一個參數肯定是null,第二參數若無參數則空起來即可。 
            System.out.println("PI的值為::"+d.doubleValue()); 
             
            Field f = lc.getDeclaredField("pos");  //私有的成員變量,反射想拿到的話,必須用getDeclaredField 
            f.setAccessible(true);   //私有的成員變量,反射想訪問的話,必須setAccessible為true 
            int value = 88; 
            f.set(rd, value); 
            System.out.println("——pos為—"+rd.getPos()); 
            f.set(rd, size); 
            System.out.println("—–恢復pos後為—"+rd.getPos()); 
             
            rd.setName("sdfasdf"); 
            f = lc.getField("name"); 
            System.out.println("————name的值為——-::"+f.get(rd)); 
            f.set(rd, "zhangsan"); 
            System.out.println("————name的值為——-::"+f.get(rd)); 
             
        }catch(Exception e){ 
            e.printStackTrace(); 
            System.out.println("異常瞭——————————————"); 
        } 
         
    } 
  
    /**
     * 理解,反射作用於數組時內容是采用什麼機制的。需要註意JDK1.4與JDK1.5 反射數組的不同。
     * @param args
     */ 
    public static void printIntArray(int[] args){ 
        System.out.println("——printIntArray invorked———"); 
        for(int arg:args){ 
            System.out.println(arg); 
        } 
         
    } 
     
    public static void printStringArray(String[] args){ 
        System.out.println("——printStringArray invorked———"); 
        for(String arg:args){ 
            System.out.println(arg); 
        } 
         
    } 
     
    public static void printIntegerArray(Integer… args){ 
        System.out.println("——printIntegerArray invorked———"); 
        for(Integer arg:args){ 
            System.out.println(arg); 
        } 
    } 
     
    public int getPos() { 
        return pos; 
    } 
  
    public void setPos(int pos) { 
        this.pos = pos; 
    } 
  
    public String getName() { 
        return name; 
    } 
  
    public void setName(String name) { 
        this.name = name; 
    } 
  
    public int getSize() { 
        return size; 
    } 
  
    public void setSize(int size) { 
        this.size = size; 
    } 
  
    public ArrayList<String> getAlist() { 
        return alist; 
    } 
  
    public void setAlist(ArrayList<String> alist) { 
        this.alist = alist; 
    } 
  

需要註意:反射在調用帶數組參數的方法時,一定要註意invork方法調用的情況,因為傳入invork方法是一個數組的話,編譯器會采用JDK1.4折方法特性將數組拆包,數組中每個元素將作為一個參數傳入到相應方法中。這樣肯定會與之前的getMethod中的數組.class有沖突,會報java.lang.IllegalArgumentException: wrong number of arguments 參數數量不對瞭。
為瞭解決此問題,有兩種方法,
一種是不讓JDK1.4插手,那麼就可將數組前面強轉成Object,這樣編譯器會使用JDK1.5的,不會將數組拆包。如:m1.invoke(rd, (Object)new String[]{"abc","bcd"});
另一種方法是,還是讓JDK1.4編,那麼外面再用一個數組包起,這個數組。這樣JDK1.4遇到這個數組的數組,拆包後還是一樣數組正好與getMethod中是一致的。如m1.invoke(rd, new Object[]{new String[]{"abc","bcd"}});
五、內省
內省對應的英文單詞為IntroSpector,它主要用於對JavaBean進行操作,JavaBean是一種特殊的Java類,其中的某些方法符合某種命名規則,如果一個Java類中的一些方法符合某種命名規則,則可以把它當作JavaBean來使用。通常的JavaBean是滿足有setter與getter方法,且方法名去掉set前綴後,若第二個字母是小寫,則屬性名為第一個字母小寫後的方法名後綴如setXxx 則 屬性名為xxx。而若第二個字母也是小寫,則屬性名是去掉前綴後所有的後綴,如setCPU,則CPU為屬性名。這點在後期學習的el表代式都有應用。
操作JavaBean另一個方法的工具包是BeanUtils,它需要loggin包的支持。
BeanUtils 官方下載地址:http://commons.apache.org/beanutils/
Logging 官方下載地址:http://commons.apache.org/logging/
具體示例代碼:
[java] 
package com.enhance; 
  
import java.beans.BeanInfo; 
import java.beans.IntrospectionException; 
import java.beans.Introspector; 
import java.beans.PropertyDescriptor; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.HashMap; 
import java.util.Map; 
  
import org.apache.commons.beanutils.BeanUtils; 
import org.apache.commons.beanutils.PropertyUtils; 
  
/**
 * 內省對應的英文單詞為IntroSpector,它主要用於對JavaBean進行操作,JavaBean是一種特殊的Java類,
 * 其中的某些方法符合某種命名規則,如果一個Java類中的一些方法符合某種命名規則,則可以把它當作JavaBean來使用。
 * 通常的JavaBean是滿足有setter與getter方法,且方法名去掉set前綴後,若第二個字母是小寫,則屬性名為第一個字母小寫後的方法名後綴
 * 如setXxx 則 屬性名為xxx。而若第二個字母也是小寫,則屬性名是去掉前綴後所有的後綴,如setCPU,則CPU為屬性名。這點在後期學習的el表代式都有應用。
 * 
 * */ 
public class IntroSpectorDemo { 
     
    public static void main(String[] args){ 
         
        ReflectDemo rfd = new ReflectDemo(); 
        rfd.setName("zhangsan"); 
        rfd.setPos(0); 
        rfd.setSize(3); 
        ArrayList<String> al = new ArrayList<String>(); 
        al.add("abc"); 
        al.add("bcd"); 
        rfd.setAlist(al); 
         
        propertyDescriptorDemo(rfd); 
        //beanInfo無法一次的得到某一個屬性的PropertyDescriptor。 
        //BeanInfo需要通過Introspector來獲取 
        beanInfoDemo(rfd); 
        beanUtilsDemo(rfd); 
    } 
  
    private static void beanUtilsDemo(ReflectDemo rfd) { 
        String name = null; 
        PropertyDescriptor pd = null ; 
        try{ 
            //通過BeanUtils的getProperty方法,獲得屬性的值 
            name = BeanUtils.getProperty(rfd, "name"); 
            System.out.println(name); 
            //通過BeanUtils的setProperty方法,獲得屬性的值 
            BeanUtils.setProperty(rfd, "name", "wangwu"); 
            System.out.println(rfd.getName()); 
            //通過BeanUtils反射,若屬性是List集合則隻能得到集合中的第一個元素 
            name = BeanUtils.getProperty(rfd, "alist"); 
            System.out.println(name); 
             
            //但Collection等集合中的元素可以通過getArrayPropertys來獲取元素中每個值 
            String[] names = BeanUtils.getArrayProperty(rfd, "alist"); 
            System.out.println("——alist——-::"+Arrays.toString(names)); 
             
            //用PropertyDescriptor來拿屬性的值 
            pd = new PropertyDescriptor("alist",rfd.getClass()); 
            Class propClazz = pd.getPropertyType(); 
            System.out.println("屬性的類型為::"+propClazz.getName()); 
             
            Method readMethod = pd.getReadMethod(); 
            Object obj = readMethod.invoke(rfd); 
            System.out.println(obj.getClass().isArray());  //false,不是數組 
            ArrayList<String> alist = (ArrayList<String>)obj; 
            System.out.println(alist); 
             
            System.out.println("—————-隔開,下面測試用Map的方式來玩轉BeanUtils—————"); 
            Map<String,Integer> map = new HashMap<String,Integer>(); 
            map.put("size", 88); 
            map.put("age", 28); 
             
            //BeanUtils可以直接操作Map對象,來獲取其中的鍵值對呢  
            String sizeStr = BeanUtils.getProperty(map, "size"); 
            String ageStr = BeanUtils.getProperty(map, "age"); 
            System.out.println("[size="+sizeStr+",age="+ageStr+"]"); 
            //還有個相似的類就是PropertyUtils,它與BeanUtils的區別是,getProperty返回的是屬性的實際類型, 
            //setProperty時,也就將實現類型值傳下其中,而不像BeanUtils都是字符串,返回的是字符串,set設置時也是字符串。 
            Integer age = (Integer)PropertyUtils.getProperty(map, "age"); 
            System.out.println(age); 
             
        }catch(Exception e){ 
            e.printStackTrace(); 
        } 
    } 
  
    private static void beanInfoDemo(ReflectDemo rfd) { 
        BeanInfo bi = null; 
        String propName = "name"; 
        try { 
            bi = Introspector.getBeanInfo(rfd.getClass()); 
            PropertyDescriptor[] pds = bi.getPropertyDescriptors(); 
            for(PropertyDescriptor pd:pds){ 
                if(propName.equals(pd.getName())){ 
                    System.out.println("beaninfo得到PropertyDescriptors數組後,再迭代PropertyDescriptor,得到name的值::"+pd.getReadMethod().invoke(rfd));                  
                } 
            } 
             
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
         
         
    } 
  
    private static void propertyDescriptorDemo(ReflectDemo rfd) { 
         
        //牛逼的PropertyDescriptor類,可以對符合JavaBean屬性的方法進行操作呢,直接得到getReadMethod與getWriteMethod 
        PropertyDescriptor pd = null ; 
         
        try { 
            pd = new PropertyDescriptor("name",rfd.getClass()); 
            Class propClazz = pd.getPropertyType(); 
            System.out.println("屬性的類型為::"+propClazz.getName()); 
             
            Method readMethod = pd.getReadMethod(); 
            Method writeMethod = pd.getWriteMethod(); 
             
            //調用讀方法,讀取目前name中的值 
            System.out.println("調用讀方法,讀name的值為::"+readMethod.invoke(rfd)); 
             
            //調用寫方法,設置name中的值 
            writeMethod.invoke(rfd, "lisi"); 
            System.out.println("調用寫方法,將name的值改變後為::"+rfd.getName()); 
             
        } catch (IntrospectionException e) { 
            e.printStackTrace(); 
        }catch (IllegalArgumentException e) { 
            e.printStackTrace(); 
        } catch (IllegalAccessException e) { 
            e.printStackTrace(); 
        } catch (InvocationTargetException e) { 
            e.printStackTrace(); 
        } 
    } 
  

——————————————————————————————————–

發佈留言