小菜毛毛技術分享

          與大家共同成長

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks
           

          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 2010-03-04 16:43 小菜毛毛 閱讀(251) 評論(0)  編輯  收藏 所屬分類: 面試
          主站蜘蛛池模板: 吉首市| 合肥市| 长白| 修武县| 三门峡市| 马龙县| 凉城县| 开鲁县| 万年县| 平山县| 固阳县| 咸宁市| 日土县| 赤城县| 阳原县| 新安县| 永仁县| 绵竹市| 英吉沙县| 阿拉善右旗| 钦州市| 河南省| 海兴县| 二连浩特市| 乡城县| 安乡县| 韶关市| 应城市| 宁城县| 二连浩特市| 通化市| 镇原县| 蓝田县| 枣阳市| 永州市| 潞城市| 广安市| 化隆| 微山县| 绥阳县| 神木县|