認識JAVA反射

目錄

一、Class類的使用與動態加載類

二、JAVA獲取方法、成員變量、構造函數信息

三、方法反射的基本操作


一、Class類的使用與動態加載類

package com.study.reflect;

/**
 * 類功能描述:Class類的使用
 *
 * @author:***
 * @createTime:2018/11/12 16:33
 */
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //任何一個類都是Class的實例對象,這個實例對象有三種表達方式 c1==c2==c3
        //c1 c2 c3 是DemoA的類類型(class type)
        DemoA demoA = new DemoA();
        Class c1 = demoA.getClass();
        Class c2 = DemoA.class;
        //Class.forName動態加載類(運行時加載類) new是靜態加載類(編譯時加載類)
        Class c3 = Class.forName("com.study.reflect.DemoA");
        System.out.println(c1 == c2 && c2 == c3 && c3 == c1);  //輸出true

        //通過類類型創建該類的對象實例 newInstance()
        ((DemoA) c1.newInstance()).print();   //輸出print

    }

}

class DemoA {
    void print() {
        System.out.println("print");
    }
}


二、JAVA獲取方法、成員變量、構造函數信息

class DemoA {
    public void print() {
        System.out.println("print");
    }

    public static void main(String[] args) throws NoSuchMethodException {
        DemoB.printMethodInfo("hello");
        DemoB.printMethodInfo(1);
    }
}

class DemoB {

    public static void printMethodInfo(Object obj) throws NoSuchMethodException {
        Class objClass = obj.getClass();
        //java.lang.String
        System.out.println("類名稱爲:" + objClass.getName());
        //String
        System.out.println(objClass.getSimpleName());
        //getMethod獲取所有public的函數,包括父類繼承而來的
        System.out.println(objClass.getMethod("toString").getName());
        //getDeclaredMethod獲取的是所有該類自己聲明的方法,無視訪問權限
        System.out.println(objClass.getDeclaredMethod("toString").getName());

        //方法也是對象
        //遍歷方法列表
        Method[] methods = objClass.getMethods();
        for (Method method : methods) {
            System.out.print(method.getName() + "(");
            //遍歷參數名,並打印
            Class[] parameterTypes = method.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                System.out.print(parameterTypes[i].getSimpleName());
                if (i < parameterTypes.length - 1) {
                    System.out.print(",");
                }
            }
            System.out.println(")");
        }

        //成員變量也是對象
        //遍歷成員變量列表
        Field[] fields = objClass.getFields();
        for (Field field : fields) {
            //遍歷成員遍歷並打印
            System.out.println(field.getType() + " " + field.getName());
        }

        //構造函數也是對象
        //構造函數列表
        Constructor[] constructors = objClass.getConstructors();
        for (Constructor constructor : constructors) {
            //構造函數方法名
            System.out.print(constructor.getName());
            //遍歷構造函數參數列表
            Class[] typeParameters = constructor.getParameterTypes();
            System.out.print("(");
            for (int i = 0; i < typeParameters.length; i++) {
                //打印參數名
                System.out.print(typeParameters[i].getSimpleName());
                if (i < typeParameters.length - 1) {
                    System.out.print(",");
                }
            }
            System.out.println(")");
        }
    }

}

三、方法反射的基本操作

 
class DemoC {
    public void test(int a, int b) {
        System.out.println(a + b);
    }

}

class DemoA {
   /**
     * 反射就是將類別的各個組成部分進行剖析,可以得到每個組成部分,就可以對每一部分進行操作
     * 在比較複雜的程序或框架中來使用反射技術,可以簡化代碼提高程序的複用性。
     * 我對invoke理解:運用反射,可以避過編譯時檢查,
     * 像方法test可以通過入參的形式調用,如果沒有test這個方法,使用傳統的調用方式,編譯都無法通過
     * 可以編寫統一的反射方法,當增加或刪除某個方法時,這個反射方法就不用做一些變動了,可以簡化代碼提高複用。
     * 類 方法 字段等都是在運行時纔會執行,通過invoke方法,可以繞過編譯。
     * 例如 ArrayList<String> arr = new ArrayList<>(); 可以通過反射繞過編譯,從而添加進其他類型的值
     * Method method = arr.getClass().getMethod("add", Object.class);
     * method.invoke(arr, 20);
     * System.out.println(arr); 輸出20,已經添加進去了
     */
    public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, InvocationTargetException, IllegalAccessException {
        DemoC democ = new DemoC();
        Method test = democ.getClass().getMethod("test", new Class[]{int.class, int.class});
        Object object = test.invoke(democ, new Object[]{10, 20});

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章