小菜毛毛技術(shù)分享

          與大家共同成長

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks
           

          JAVA語言中的反射機(jī)制:
              在Java 運(yùn)行時(shí) 環(huán)境中,對于任意一個(gè)類,能否知道這個(gè)類有哪些屬性和方法?
              對于任意一個(gè)對象,能否調(diào)用他的方法?這些答案是肯定的,這種動態(tài)獲取類的信息,以及動態(tài)調(diào)用類的方法的功能來源于JAVA的反射。從而使java具有動態(tài)語言的特性。

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

            Java 反射相關(guān)的API簡介:
                位于java。lang。reflect包中
                  --Class類:代表一個(gè)類
                  --Filed類:代表類的成員變量
                  --Method類:代表類的方法
                  --Constructor類:代表類的構(gòu)造方法
                  --Array類:提供了動態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法。該類中的所有方法都是靜態(tài)方法


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


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


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

          ----運(yùn)行時(shí)生成instance
               想生成對象的實(shí)體,在反射動態(tài)機(jī)制中有兩種方法,一個(gè)針對無變量的構(gòu)造方法,一個(gè)針對帶參數(shù)的
          構(gòu)造方法,,如果想調(diào)用帶參數(shù)的構(gòu)造方法,就比較的麻煩,不能直接調(diào)用Class類中的newInstance()
          ,而是調(diào)用Constructor類中newInstance()方法,首先準(zhǔn)備一個(gè)Class[]作為Constructor的參數(shù)類型。
          然后調(diào)用該Class對象的getConstructor()方法獲得一個(gè)專屬的Constructor的對象,最后再準(zhǔn)備一個(gè)
          Object[]作為Constructor對象昂的newInstance()方法的實(shí)參。
                在這里需要說明的是 只有兩個(gè)類擁有newInstance()方法,分別是Class類和Constructor類
          Class類中的newInstance()方法是不帶參數(shù)的,而Constructro類中的newInstance()方法是帶參數(shù)的
          需要提供必要的參數(shù)。

              例:
                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);

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

          ----運(yùn)行時(shí)調(diào)用Field內(nèi)容
              變更Field不需要參數(shù)和自變量,首先調(diào)用Class的getField()并指定field名稱,獲得特定的Field對象后
          便可以直接調(diào)用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.      * 在這個(gè)類里面存在有copy()方法,根據(jù)指定的方法的參數(shù)去 構(gòu)造一個(gè)新的對象的拷貝  
          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.         //通過默認(rèn)構(gòu)造方法去創(chuàng)建一個(gè)新的對象,getConstructor的視其參數(shù)決定調(diào)用哪個(gè)構(gòu)造方法   
          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.             //獲取數(shù)組中對應(yīng)的屬性   
          33.             Field field=fields[i];   
          34.                
          35.             String fieldName=field.getName();   
          36.             String stringLetter=fieldName.substring(01).toUpperCase();   
          37.                
          38.             //獲得相應(yīng)屬性的getXXX和setXXX方法名稱   
          39.             String getName="get"+stringLetter+fieldName.substring(1);   
          40.             String setName="set"+stringLetter+fieldName.substring(1);   
          41.                
          42.             //獲取相應(yīng)的方法   
          43.             Method getMethod=classType.getMethod(getName, new Class[]{});   
          44.             Method setMethod=classType.getMethod(setName, new Class[]{field.getType()});   
          45.                
          46.             //調(diào)用源對象的getXXX()方法   
          47.             Object value=getMethod.invoke(obj, new Object[]{});   
          48.             System.out.println(fieldName+" :"+value);   
          49.                
          50.             //調(diào)用拷貝對象的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.      * 此類根據(jù)反射來創(chuàng)建  
          9.      * 一個(gè)動態(tài)的數(shù)組   
          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);  //指定數(shù)組的類型和大小   
          16.            
          17.          //對索引為5的位置進(jìn)行賦值   
          18.         Array.set(array, 5"hello");   
          19.            
          20.         String s=(String)Array.get(array, 5);   
          21.            
          22.         System.out.println(s);   
          23.            
          24.            
          25.         //循環(huán)遍歷這個(gè)動態(tài)數(shù)組   
          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)  編輯  收藏 所屬分類: 面試
          主站蜘蛛池模板: 城步| 古田县| 五大连池市| 略阳县| 松原市| 宜城市| 香港 | 凉城县| 监利县| 和政县| 鹤峰县| 平南县| 双柏县| 含山县| 泌阳县| 攀枝花市| 沙坪坝区| 临夏县| 斗六市| 边坝县| 同德县| 昌平区| 哈密市| 定陶县| 荥阳市| 龙胜| 舞阳县| 星座| 卫辉市| 凤翔县| 济阳县| 策勒县| 北宁市| 八宿县| 博客| 丹东市| 集安市| 光泽县| 县级市| 赣榆县| 合川市|