隨筆 - 33, 文章 - 0, 評論 - 12, 引用 - 0
          數據加載中……

          JAVA反射機制的學習

          JAVA語言中的反射機制:
              在Java 運行時 環境中,對于任意一個類,能否知道這個類有哪些屬性和方法?
              對于任意一個對象,能否調用他的方法?這些答案是肯定的,這種動態獲取類的信息,以及動態調用類的方法的功能來源于JAVA的反射。從而使java具有動態語言的特性。

            JAVA反射機制主要提供了以下功能:
                1.在運行時判斷任意一個對象所屬的類
                2.在運行時構造任意一個類的對象
                3.在運行時判斷任意一個類所具有的成員變量和方法(通過反射甚至可以調用private方法)
                4.在運行時調用任意一個對象的方法(*****注意:前提都是在運行時,而不是在編譯時)

            Java 反射相關的API簡介:
                位于java。lang。reflect包中
                  --Class類:代表一個類
                  --Filed類:代表類的成員變量
                  --Method類:代表類的方法
                  --Constructor類:代表類的構造方法
                  --Array類:提供了動態創建數組,以及訪問數組的元素的靜態方法。該類中的所有方法都是靜態方法


          ----Class類
               在 java 的Object類中的申明了數個應該在所有的java類中被改寫的methods:
          hashCode(), equals(),clone(),toString(),getClass()等,其中的getClass()返回yige
          Class 類型的對象。
               Class類十分的特殊,它和一般的類一樣繼承自Object,其實體用以表達java程序運行
          時的 class和 interface,也用來表達 enum,array,primitive,Java Types 以及關鍵字void
          ,當加載一個類,或者當加載器(class loader)的defineClass()被JVM調用,便產生一個Class
          對象,
               Class是Reflection起源,針對任何你想探勘的class(類),唯有現為他產生一個Class
          的對象,接下來才能經由后者喚起為數十多個的反射API。


               Java允許我們從多種途徑為一個類class生成對應的Class對象。
                    --運用 getClass():Object類中的方法,每個類都擁有此方法 
                                          String str="abc";
                                          Class cl=str.getClass();


                   --運用 Class。getSuperclass():Class類中的方法,返回該Class的父類的Class
                   --運用 Class。forName()靜態方法:
                   --運用 ,Class:類名.class
                   --運用primitive wrapper classes的TYPE語法: 基本類型包裝類的TYPE,如:Integer.TYPE
                                注意:TYPE的使用,只適合原生(基本)數據類型

          ----運行時生成instance
               想生成對象的實體,在反射動態機制中有兩種方法,一個針對無變量的構造方法,一個針對帶參數的
          構造方法,,如果想調用帶參數的構造方法,就比較的麻煩,不能直接調用Class類中的newInstance()
          ,而是調用Constructor類中newInstance()方法,首先準備一個Class[]作為Constructor的參數類型。
          然后調用該Class對象的getConstructor()方法獲得一個專屬的Constructor的對象,最后再準備一個
          Object[]作為Constructor對象昂的newInstance()方法的實參。
                在這里需要說明的是 只有兩個類擁有newInstance()方法,分別是Class類和Constructor類
          Class類中的newInstance()方法是不帶參數的,而Constructro類中的newInstance()方法是帶參數的
          需要提供必要的參數。
              例:
                Class c=Class.forName("DynTest");
                Class[] ptype=new Class[]{double.class,int.class};
                Constructor ctor=c.getConstructor(ptypr);
                Object[] obj=new Object[]{new Double(3.1415),new Integer(123)};
                Object object=ctor.newInstance(obj);
                System.out.println(object);

          ----運行時調用Method
              這個動作首先準備一個Class[]{}作為getMethod(String name,Class[])方法的參數類型,接下來準備一個
          Obeject[]放置自變量,然后調用Method對象的invoke(Object obj,Object[])方法。
               注意,在這里調用

          ----運行時調用Field內容
              變更Field不需要參數和自變量,首先調用Class的getField()并指定field名稱,獲得特定的Field對象后
          便可以直接調用Field的 get(Object obj)和set(Object obj,Object value)方法

          java 代碼
          1. package cn.com.reflection;   
          2.   
          3. import java.lang.reflect.Field;   
          4. import java.lang.reflect.InvocationTargetException;   
          5. import java.lang.reflect.Method;   
          6.   
          7. public class ReflectTester {   
          8.   
          9.     /**  
          10.      * 在這個類里面存在有copy()方法,根據指定的方法的參數去 構造一個新的對象的拷貝  
          11.      * 并將他返回  
          12.      * @throws NoSuchMethodException   
          13.      * @throws InvocationTargetException   
          14.      * @throws IllegalAccessException   
          15.      * @throws InstantiationException   
          16.      * @throws SecurityException   
          17.      * @throws IllegalArgumentException   
          18.      */  
          19.     public Object copy(Object obj) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{   
          20.            
          21.         //獲得對象的類型   
          22.         Class classType=obj.getClass();   
          23.         System.out.println("該對象的類型是:"+classType.toString());   
          24.            
          25.         //通過默認構造方法去創建一個新的對象,getConstructor的視其參數決定調用哪個構造方法   
          26.         Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});   
          27.            
          28.         //獲得對象的所有屬性   
          29.         Field[] fields=classType.getDeclaredFields();   
          30.            
          31.         for(int i=0;i
          32.             //獲取數組中對應的屬性   
          33.             Field field=fields[i];   
          34.                
          35.             String fieldName=field.getName();   
          36.             String stringLetter=fieldName.substring(01).toUpperCase();   
          37.                
          38.             //獲得相應屬性的getXXX和setXXX方法名稱   
          39.             String getName="get"+stringLetter+fieldName.substring(1);   
          40.             String setName="set"+stringLetter+fieldName.substring(1);   
          41.                
          42.             //獲取相應的方法   
          43.             Method getMethod=classType.getMethod(getName, new Class[]{});   
          44.             Method setMethod=classType.getMethod(setName, new Class[]{field.getType()});   
          45.                
          46.             //調用源對象的getXXX()方法   
          47.             Object value=getMethod.invoke(obj, new Object[]{});   
          48.             System.out.println(fieldName+" :"+value);   
          49.                
          50.             //調用拷貝對象的setXXX()方法   
          51.             setMethod.invoke(objectCopy,new Object[]{value});   
          52.                
          53.                
          54.         }   
          55.            
          56.         return objectCopy;   
          57.            
          58.     }   
          59.        
          60.        
          61.     public static void main(String[] args) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {   
          62.         Customer customer=new Customer();   
          63.         customer.setName("hejianjie");   
          64.         customer.setId(new Long(1234));   
          65.         customer.setAge(19);   
          66.            
          67.         Customer customer2=null;   
          68.         customer2=(Customer)new ReflectTester().copy(customer);   
          69.         System.out.println(customer.getName()+" "+customer2.getAge()+" "+customer2.getId());   
          70.            
          71.         System.out.println(customer);   
          72.         System.out.println(customer2);   
          73.            
          74.   
          75.     }   
          76.   
          77. }   
          78.   
          79.   
          80. class Customer{   
          81.        
          82.     private Long id;   
          83.        
          84.     private String name;   
          85.        
          86.     private int age;   
          87.        
          88.        
          89.     public Customer(){   
          90.            
          91.     }   
          92.   
          93.     public int getAge() {   
          94.         return age;   
          95.     }   
          96.   
          97.   
          98.     public void setAge(int age) {   
          99.         this.age = age;   
          100.     }   
          101.   
          102.   
          103.     public Long getId() {   
          104.         return id;   
          105.     }   
          106.   
          107.   
          108.     public void setId(Long id) {   
          109.         this.id = id;   
          110.     }   
          111.   
          112.   
          113.     public String getName() {   
          114.         return name;   
          115.     }   
          116.   
          117.   
          118.     public void setName(String name) {   
          119.         this.name = name;   
          120.     }   
          121.        
          122. }  


          java 代碼
          1. package cn.com.reflection;   
          2.   
          3. import java.lang.reflect.Array;   
          4.   
          5. public class ArrayTester1 {   
          6.   
          7.     /**  
          8.      * 此類根據反射來創建  
          9.      * 一個動態的數組   
          10.      */  
          11.     public static void main(String[] args) throws ClassNotFoundException {   
          12.            
          13.         Class classType=Class.forName("java.lang.String");   
          14.            
          15.         Object array= Array.newInstance(classType,10);  //指定數組的類型和大小   
          16.            
          17.          //對索引為5的位置進行賦值   
          18.         Array.set(array, 5"hello");   
          19.            
          20.         String s=(String)Array.get(array, 5);   
          21.            
          22.         System.out.println(s);   
          23.            
          24.            
          25.         //循環遍歷這個動態數組   
          26.         for(int i=0;i<((String[])array).length;i++){   
          27.                
          28.             String str=(String)Array.get(array, i);   
          29.                
          30.             System.out.println(str);   
          31.         }   
          32.   
          33.     }   
          34.   
          35. }   

          posted on 2011-05-23 13:37 建華 閱讀(585) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 武冈市| 五峰| 洛川县| 浮梁县| 逊克县| 包头市| 静宁县| 阿克苏市| 陇川县| 宝应县| 五华县| 富蕴县| 定州市| 乌什县| 邢台县| 巴彦淖尔市| 南丹县| 西乡县| 云阳县| 惠水县| 镇坪县| 望城县| 明溪县| 固安县| 海原县| 牟定县| 金门县| 镇江市| 长武县| 工布江达县| 云浮市| 安阳市| 南皮县| 博白县| 大同市| 定陶县| 江达县| 门源| 平遥县| 石城县| 永顺县|