国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

java reflect 機制

2019-11-17 04:05:11
字體:
來源:轉載
供稿:網友
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(0, 1).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. }   

注:

getMethod只返回用public修飾的方法,包括自定義的、實現的接口的方法、繼承的父類的方法

按以下順序查找:class -> superclass -> interface (in the declared order)

getDeclaredMethod返回自定義的方法,不包括從父類繼承的方法

另外getField與getDeclaredField、getConstructor與getDeclaredConstructor的區別與這個差不多

不過getField按以下順序查找:class -> interface (in the declared order) -> superclass

比如定義如下class

public class ClassA{

    private int field0=100;

}

ClassA應該保存了field0的默認值100,但是無論Class或者Field類的API都未提供如何拿到這個默認值的方法。

為這個變量寫一個SET方法通過方法反射進行賦值

    public Object setFileMethodInvoke(Object obj,String fieldName,Object value) throws Exception{   

       

        //獲得對象的類型   

        Class classType=obj.getClass();   

//        System.out.println("該對象的類型是:"+classType.toString());   

           

        //通過默認構造方法去創建一個新的對象,getConstructor的視其參數決定調用哪個構造方法   

//        Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});   

           

        //獲得對象的所有屬性   

//        Field[] fields=classType.getDeclaredFields();   

           

       

            Field field=classType.getDeclaredField(fieldName);  

            String stringLetter=fieldName.substring(0, 1).toUpperCase();   

               

            //獲得相應屬性的getXXX和setXXX方法名稱   

//            String getName="get"+stringLetter+fieldName.substring(1);   

            String setName="set"+stringLetter+fieldName.substring(1);   

            System.out.println("aaaaaaa::::"+setName+"::"+value);

            //獲取相應的方法   

//            Method getMethod=classType.getMethod(getName, new Class[]{});   

            Method setMethod=classType.getMethod(setName, new Class[]{field.getType()});   

            System.out.println("aaaaaaa::::"+setMethod+":::"+value);

            //調用源對象的getXXX()方法   

//            Object value=getMethod.invoke(obj, new Object[]{});   

//            System.out.println(fieldName+" :"+value);   

               

            //調用拷貝對象的setXXX()方法   

            setMethod.invoke(obj,new Object[]{value});    

               

               

           

           

        return obj;   

           

    }

Class a=ClassA.class;

Object o=a.newInstance(); //不這樣如何獲得初值

Field f=a.getDeclaredField("field0");

f.setAccessible(true);

System.out.print(f.get(o)); 
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 灵石县| 萍乡市| 红原县| 揭东县| 玉树县| 博爱县| 梅河口市| 屏南县| 武邑县| 沅陵县| 江城| 台南县| 通州市| 孟州市| 苗栗县| 黄大仙区| 玛多县| 鱼台县| 峨眉山市| 图木舒克市| 南宁市| 濮阳市| 密山市| 乐至县| 梧州市| 昭苏县| 襄城县| 宜宾县| 牡丹江市| 肇州县| 万全县| 文登市| 马山县| 延吉市| 邹城市| 临夏县| 汉源县| 翁源县| 汉中市| 东宁县| 巍山|