Java反射機制

來源:互聯網
上載者:User

標籤:ram   generate   zh-cn   modifier   param   利用   cep   ==   時間   

     最近學習中遇到反射機制,可是老師只是輕描淡寫的解釋了一通,還是自己查資料補充一下。

Java反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態擷取的資訊以及動態調用對象的方法的功能稱為Java語言的反射機制。

一、Class類

     1、Class是一個類,一個描述類的類(也就是描述類本身),封裝了描述方法的Method,描述欄位的Filed,描述構造器的Constructor等屬性
    2、對象照鏡子後(反射)可以得到的資訊:某個類的資料成員名、方法和構造器、某個類到底實現了哪些介面。
    3、對於每個類而言,JRE 都為其保留一個不變的 Class 類型的對象。
        一個 Class 對象包含了特定某個類的有關資訊。換句話說:任何類都是Class類的執行個體對象
    4、Class 對象只能由系統建立對象
    5、一個類在 JVM 中只會有一個Class執行個體

 

二、反射機制

 反射是Java中一種強大的工具,能夠使我們很方便的建立靈活的代碼,這些代碼可以再運行時裝配,無需在組件之間進行原始碼連結。

   作用:

  1. 在運行時判斷任意一個對象所屬的類;
  2. 在運行時擷取類的對象;
  3. 在運行時訪問java對象的屬性,方法,構造方法等。

  

 

  反射的特點:

             為什麼要用反射機制?直接建立對象不就可以了嗎,這就涉及到了動態與靜態概念。

靜態編譯:在編譯時間確定類型,綁定對象,即通過。
動態編譯:運行時確定類型,綁定對象。動態編譯最大限度發揮了java的靈活性,體現了多態的應用,有以降低類之間的藕合性

反射機制的優點:可以實現動態建立對象和編譯,體現出很大的靈活性(特別是在J2EE的開發中它的靈活性就表現的十分明顯)。通過反射機制我們可以獲得類的各種內容,進行了反編譯。對於JAVA這種先編譯再啟動並執行語言來說,反射機制可以使代碼更加靈活,更加容易實現物件導向。

舉例:一個大型的軟體,當程式編譯後,發布了,都會在後期不斷的更新以完善整個程式,我們不可能要使用者把以前的卸載,再重新安裝新的版本,假如這樣的話,這個軟體肯定是沒有多少人用的。採用靜態話,需要把整個程式重新編譯一次才可以實現功能的更新,而採用反射機制的話,它就可以不用卸載,只需要在運行時才動態建立和編譯,就可以實現該功能。 想一下,王者榮耀每次出新英雄或者出新皮膚的時候都會有更新,使用者在更新的時候知只是下載一個小的程式包進行安裝,而不用重新安裝整個王者榮耀遊戲,這就是採用動態編譯的例子。

反射機制的缺點:對效能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什麼並且它 滿足我們的要求。這類操作總是慢於只直接執行相同的操作。

 三、Class中實現反射機制的類

java.lang.Class;                

java.lang.reflect.Constructor; 

java.lang.reflect.Field;        

java.lang.reflect.Method;

java.lang.reflect.Modifier;

四、反射機制擷取類有三種方法

在利用反射擷取類的對象,對象的屬性,方法,構造方法等的時候都需要建立類的類類型

 

 

package com.neuedu.reflect;/* * 項目名稱:Java-Reflect * @author:wzc* @date 建立時間:2017年8月28日 下午8:41:29* @Description:擷取類的類類型* @parameter  *   */public class JavaDemo1 {    public static void main(String[] args) {//Food的執行個體對象如何表示    Food food1=new Food();        /*     * Food這個類也是一個執行個體對象,Class類的執行個體對象     * 任何一個類都是Class的執行個體對象,三種表示方式     * 第一種表達方式--->實際上在告訴我們任何一個類都有一個隱含的靜態成員class        */        Class class1=Food.class;    //第二種表示方式,已知該類的對象getClass    Class class2=food1.getClass();    /*     * c1,c2表示了Food類的類類型(class type)     * 任何類都是class類的執行個體對象     * c1 c2都代表了Food的類類型,一個類只可能是Class類的一個執行個體對象     */    System.out.println(class1==class2);    //第三種表達方式    Class class3=null;    try {class3=Class.forName("com.neuedu.reflect.Food");} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}    System.out.println(class2==class3);    }//建立一個Food類class Food{public void print(){System.out.println("hello Food");}}

 

 五、建立對象

  擷取類的類類型以後我們就可以利用類類型建立該類的對象

 

package com.neuedu.reflect;/* * 項目名稱:Java-Reflect * @author:wzc* @date 建立時間:2017年8月28日 下午8:41:29* @Description:擷取類的類類型* @parameter  *   */public class JavaDemo1 {    public static void main(String[] args) {//Food的執行個體對象如何表示    Food food1=new Food();        /*     * Food這個類也是一個執行個體對象,Class類的執行個體對象     * 任何一個類都是Class的執行個體對象,三種表示方式     * 第一種表達方式--->實際上在告訴我們任何一個類都有一個隱含的靜態成員class        */        Class class1=Food.class;    //第二種表示方式,已知該類的對象getClass    Class class2=food1.getClass();    /*     * c1,c2表示了Food類的類類型(class type)     * 任何類都是class類的執行個體對象     * c1 c2都代表了Food的類類型,一個類只可能是Class類的一個執行個體對象     */    System.out.println(class1==class2);    //第三種表達方式    Class class3=null;    try {class3=Class.forName("com.neuedu.reflect.Food");} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}    System.out.println(class2==class3);    //我們可以通過類的類類型建立類的對象執行個體    try {Food food2 = (Food) class1.newInstance();food2.print();    } catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//建立一個Food類class Food{public void print(){System.out.println("hello Food");}}

 

 六、擷取類的相關資訊:    類名,方法名,方法的傳回值類型,方法的參數列表
package com.neuedu.Uttil;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;/* * 項目名稱:Java-Reflect * @author:wzc* @date 建立時間:2017年8月29日 下午1:22:15* @Description: 1.利用反射列印類的資訊*               2.利用反射列印類的成員變數*               3.利用反射列印類的構造方法* @parameter  *   */public class Uttil {/* * 列印類的資訊,列印類的傳回值類型,類類名,參數列表 *  * */public static void PrintClass(Object obj){Class  cInt=obj.getClass();System.out.println("類的名稱:"+cInt.getName());/* * Method類,方法對象 * 一個成員方法就是一個Method對象 * getMethods()方法擷取的是所有的public的函數,包括父類繼承而來的 * getDeclaredMethods()擷取的是所有該類自己聲明的方法, *  * */Method[] ms=cInt.getMethods();System.out.println("[類的傳回值類型],[類的名稱],[類的參數列表]");for (int i = 0; i < ms.length; i++) {//得到方法的傳回值類型的類類型Class returnType=ms[i].getReturnType();System.out.print(returnType.getName()+" ");//得到方法的名稱System.out.print(ms[i].getName()+"(");//擷取參數類型Class [] paramTypes=ms[i].getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName()+",");}System.out.println(")");}}}

 測試一下:

public class JunitTest {@Testpublic void test() {String string="hello";//Uttil.PrintClass(string);}}

 執行結果:

 

七、擷取類的屬性
/* * 成員變數也是對象 * java.lang.reflect.Field; * Filed類封裝了關於成員變數的操作 * getFields()方法擷取的是所有的public的成員變數的資訊 * getDeclaredFields擷取的是該類自己聲明的成員變數的資訊 *  *  * */public static void printFieldInfo(Object obj) {//擷取類的成員變數Class class1=obj.getClass();Field[] fields=class1.getDeclaredFields();for (Field field : fields) {//得到成員變數的類型的類類型//得到成員變數的類型名Class fieldType=field.getType();String   typeName=fieldType.getName();//得到成員變數的名稱String   fieldName=field.getName();System.out.println(typeName+" "+fieldName);}}

 測試一下:

        @Testpublic void test() {Uttil.printFieldInfo(new Integer(1));}

 結果:

八、擷取類的構造方法
  /*     * 列印對象的建構函式     * */public static void  printConMessage(Object obj){    Class class1=obj.getClass();    /*     * 建構函式也是對象     * java.lang.Contructor中封裝了建構函式的資訊     * getConstructors擷取所有的public的建構函式     * getDeclaredContructors得到所有的建構函式     *      *      */    Constructor[] ct=class1.getConstructors();    for (Constructor constructor : ct) {System.out.print(constructor.getName()+"(");//擷取建構函式的參數列表--->得到的是參數列表的類類型Class[] paramTypes=constructor.getParameterTypes();for (Class class2 : paramTypes) {System.out.print(class2.getName());}System.out.println(")");}}

 測試一下:

@Testpublic void test() {String string="hello";Uttil.printConMessage(string);}

 結果:

九、通過反射來執行對象的方法
package com.neuedu.reflect;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/* * 項目名稱:Java-Reflect * @author:wzc* @date 建立時間:2017年8月29日 下午6:45:21* @Description:通過反射執行類的方法* * @parameter  *   */public class RunMethod {   public static void main(String[] args) {   Student student=new Student("張三", 25);   //1.要擷取方法,首先要擷取該方法的類類型,   Class stuClass = student.getClass();   /*    * 2.擷取方法、名稱和參數列表    * getMethod擷取的是public方法    * getDelcaredMethod自己聲明的方法    */   try {//stuClass.getMethod("getName",new Class[]{})//stuClass.getMethod("getName"); Method m1=stuClass.getMethod("getName", null);//3.方法的反射操作-----以前:student.getName(); //m1.invoke(obj,args..);  //方法的反射操作是用m1對象來進行方法的調用 //方法如果沒有傳回值返回null,有傳回值返回具體的傳回值,並轉換成Object m1.invoke(student);  System.out.println("=============="); m1=stuClass.getMethod("getAge", null); Object object=m1.invoke(student, null); System.out.println("=============="); //m1=stuClass.getMethod("getAge", int.class); m1=stuClass.getMethod("getAge", new Class[]{int.class}); m1.invoke(student, 2); } catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//student類class Student{private String name;private int age;public Student(){}public Student(String name,int age){this.name=name;this.age=age;}//無參數方法public void getName(){   System.out.println("name:"+name);}//無參數方法public void getAge(){System.out.println("age:"+age);}//有參數的方法public void getAge(int num){System.out.println(num+"年前age:"+(age-num));}public void studentIn(){System.out.println("name:"+name+",age:"+age);}}

 今天只是記錄一些反射最基礎的理論,之後會在寫一些反射的應用,只有應用了才能更好的理解反射的概念。

 

Java反射機制

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.