JAVA反射

反射是Java 語言的特征之一,它允許運行中的Java程序獲取自身的信息,并且可以操作類或?qū)ο蟮膬?nèi)部屬性。通過反射,可以在運行時獲得程序中每一個類型的成員和成員的信息。程序中一般的對象的類型都是在編譯期就確定下來的,而Java反射機制可以動態(tài)地創(chuàng)建對象并調(diào)用其屬性,這樣的對象的類型在編譯期是未知的。

反射的核心是JVM在運行時才動態(tài)加載類或調(diào)用方法/訪問屬性,它不需要事先知道運行對象是誰。

Java反射框架主要提供以下功能:

  1. 在運行時判斷任意一個對象所屬的類;
  2. 在運行時構(gòu)造任意一個類的對象;
  3. 在運行時判斷任意一個類所具有的成員變量和方法;
  4. 在運行時調(diào)用任意一個對象的方法

當我們在使用IDE(如Eclipse,IDEA)時,當我們輸入一個對象或類并想調(diào)用它的屬性或方法時,一按點號,編譯器就會自動列出它的屬性或方法,這里就會用到反射。

反射最重要的用途就是開發(fā)各種通用框架。

操作反射常用的類:Constructor、Field、Method、Array位于java.lang.reflect包中。
通過反射獲取類的信息分為兩步:

  1. 獲取Class對象

    • 調(diào)用對象的getClass()方法
    • 調(diào)用類的class屬性
    • 調(diào)用Class類的forName()方法
  2. 通過Class對象獲取信息

    • 訪問Class對應(yīng)的類的構(gòu)造方法
    • 訪問Class對應(yīng)的類的方法
    • 訪問Class對應(yīng)的類的屬性

訪問Class對應(yīng)的類的構(gòu)造方法

訪問Class對應(yīng)的類的構(gòu)造方法 說明
Constructor getConstructor(Class[ ] params) 返回此Class對象所包含的類的指定的public構(gòu)造方法
Constructor[ ] getConstructors( ) 返回此Class對象所包含的類的所有的public構(gòu)造方法
Constructor getDeclaredConstructor(Class[ ] params) 返回此Class對象所包含的類的聲明的指定的構(gòu)造方法
Constructor[ ] getDeclaredConstructors( ) 返回此Class對象所包含的類的聲明的所有構(gòu)造方法

訪問Class對應(yīng)的類的方法

訪問Class對應(yīng)的類的方法 說明
Method getMethod(String name, Class[ ] params) 返回此Class對象所包含的類的指定的public方法
Method[ ] getMethods( ) 返回此Class對象所包含的類的所有的public方法
Method getDeclaredMethod(String name, Class[ ] params) 返回此Class對象所包含的類的聲明的指定的方法
Method[ ] getDeclaredMethods( ) 返回此Class對象所包含的類的聲明的所有方法

訪問Class對應(yīng)的類的屬性

訪問Class對應(yīng)的類的屬性 說明
Field getField(String name) 返回此Class對象所包含的類的指定的public屬性
Field[ ] getFields( ) 返回此Class對象所包含的類的所有的public屬性
Field getDeclaredField(String name) 返回此Class對象所包含的類的聲明的指定的屬性
Field[ ] getDeclaredFields( ) 返回此Class對象所包含的類的聲明的所有屬性

Array類操作數(shù)組

Array類里定義了大量靜態(tài)方法,通過類名直接調(diào)用。
這里的Array和集合框架里的Arrays不一樣,他們的相同點都是定義了大量靜態(tài)方法,都是數(shù)組的操作,Array位于java.lang.relect包,是動態(tài)創(chuàng)建并操作數(shù)組;Arrays位于java.util包,是一個工具類,其中包含了一些方法可直接實現(xiàn)數(shù)組的排序、搜索等。

下面結(jié)合代碼做下說明:

public class Demo {
          //調(diào)用class對象會拋出大量異常,這里為簡化代碼,直接拋給jvm
    public static void main(String[] args) throws Exception {
        Student stu = new Student("張三",23);
        
        //獲取Class對象
        //方法一:forName()方法,必須要完整的包名加類名
        Class<?> stuClass = Class.forName("reflect.Student");
        //方法二:類的class屬性
        Class<?> cla1 = Student.class;
        //方法三:getClass()方法
        Class<?> cla2 = stu.getClass();
        System.out.println(stuClass.getName());
        
        //獲取聲明的所有構(gòu)造方法
        Constructor<?>[] constructor = stuClass.getConstructors();
        for (int i = 0; i < constructor.length; i++) {
            System.out.println(constructor[i].toString());
        }
        //獲取指定的一個有參構(gòu)造方法
        Constructor<?> con1 = stuClass.getDeclaredConstructor(String.class,int.class);
        Object obj = con1.newInstance("tom",20);  //使用Class對象的newInstance()方法創(chuàng)建對象
        ((Student)obj).shwoInfo();
        
        //獲取聲明的所有屬性
        Field[] fields = stuClass.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            System.out.println(fields[i].toString());
        }
        //獲取public name屬性,并改變其值
        Field fieldname = stuClass.getDeclaredField("name");
        fieldname.set(stu, "王小二");//set方法給屬性賦值
        String nameStr = (String) fieldname.get(stu); //get方法取出屬性的值
        System.out.println(nameStr);
        //獲取private age屬性,并改變其值
        Field fieldAge = stuClass.getDeclaredField("age");
        fieldAge.setAccessible(true); //改變屬性訪問權(quán)限
        fieldAge.set(stu, 58);
        int ageInt = fieldAge.getInt(stu);
        System.out.println(ageInt);
        
        //獲得聲明的所有方法
        Method[] methods = stuClass.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            System.out.println(methods[i].toString());//以字符串形式打印出方法名
        }
        //獲得聲明的指定方法,傳值并調(diào)用
        Method m1 = stuClass.getDeclaredMethod("sayHelloTo", String.class);
        m1.invoke(null, "jerry");//這里的null是因為調(diào)用的方法是靜態(tài)方法,不用傳對象
        //獲得其中一個方法,直接調(diào)用
        Method m2 = stuClass.getDeclaredMethod("shwoInfo");
        m2.invoke(stu);//用invoke()調(diào)用方法時需要傳一個對象

        //Array操作數(shù)組
        Object arr = Array.newInstance(int.class, 3);//創(chuàng)建元素為3的int數(shù)組
        for (int i = 0; i < Array.getLength(arr); i++) {
            Array.set(arr, i, 2*i); //循環(huán)給元素賦值
        }
        for (int i = 0; i < Array.getLength(arr); i++) {
            System.out.println(Array.get(arr, i));//循環(huán)取值
        }
        Array.set(array, 0, 99);//指定元素賦值
        System.out.println(Array.get(array, 0));//指定元素取值
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容