java輔助功能,Reflection 反射詳解

一、反射的作用

Java裏面的反射可以幫助我們在運行程序時候加載、使用編譯期間完全未知的class, 簡單來說就是Java可以加載一個運行時候才得知名稱的class, 獲得其完整的構造,並生成實例化對象,對其成員變量賦值,調用其方法等等。

二、應用場景

在具體的研發中,通過反射獲取類的實例,大大提高系統的靈活性和擴展性,同時由於反射的性能較低,而且它極大的破壞了類的封裝性(通過反射獲取類的私有方法和屬性),在大部分場景下並不適合使用反射,但是在大型的一些框架中,會大範圍使用反射來幫助架構完善一些功能。

三、使用反射前的準備

①. 聲明一個接口

public interface IHumanAction {
    void eat();
}

②. 創建一個具體的類,注意類各個方法的修飾屬性

public class Human implements IHumanAction {
    private int age;
    public String name;

    public Human() {
    }

    Human(String name) {
        this.name = name;
    }

    protected Human(int age) {
        this.age = age;
    }

    public Human(int age, String name, String sex) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    protected void eatApple() {
        System.out.println("eat apple");
    }

    void playGame() {
    }

    @Override
    public void eat() {
        System.out.println(this.name + " performs eat");
    }

    @Override
    public String toString() {
        return "Human{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

四、通過反射獲取類所實現的接口、類所繼承的超類、類的構造函數、類的方法、類的成員

①. 獲取類所實現的接口和所繼承的超類

Class clz = Class.forName("Human");
----------
if (clz != null) {
            Class superclass = clz.getSuperclass();
            System.out.println("該類的父類:" + superclass.getName());
            Class[] interfaces = clz.getInterfaces();
            for (Class class1 : interfaces) {
                System.out.println("該類實現的接口:" + class1.getName());
            }
        }

②. 內容獲取類的構造函數

Class clz = Class.forName("Human");
----------
public static void method1_getConstructors() {
        System.out.println("該類的構造函數(getConstructors): ");
        if (clz != null) {
            Constructor[] constructors = clz.getConstructors();
            for (Constructor constructor : constructors) {
                int modifiers = constructor.getModifiers();
                System.out.println(Modifier.toString(modifiers) + " "+constructor.getName());
            }
        }
    }
----------
public static void method2_getDeclaredConstructors() {
        System.out.println("該類的構造函數(getDeclaredConstructors): ");
        if (clz != null) {
            Constructor[] declaredConstructors = clz.getDeclaredConstructors();
            for (Constructor constructor : declaredConstructors) {
                int modifiers = constructor.getModifiers();
                System.out.println(Modifier.toString(modifiers) + " " + constructor.getName());
            }
        }
    }
----------
public static void method3_getDeclaredConstructorsByParamType() {
        System.out.println("該類的構造函數(getDeclaredConstructors(int type)): ");
        if (clz != null) {
            try {
                Class param = int.class;
                Constructor declaredConstructor = clz.getDeclaredConstructor(param);
                if (declaredConstructor != null)                    System.out.println(Modifier.toString(declaredConstructor.getModifiers()) + " "
                            + declaredConstructor.getName());
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }
        }
    }
----------
public static void method4_getConstructorsByParamType() {
        System.out.println("該類的構造函數(getConstructors(int type)): ");
        if (clz != null) {
            try {
                Class param = int.class;
                Constructor constructor = clz.getConstructor(param);
                if (constructor != null)
                    System.out.println(Modifier.toString(constructor.getModifiers()) + " " + constructor.getName());
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }
        }
    }

getConstuctors(),獲取的構造函數全部是public屬性的。
getConstuctor(Class …params),根據參數,從所有public屬性的構造函數中獲取相關構造函數。getDelaredConstructors(),獲取所有的構造函數。
getDelaredConstructor(Class … params),根據參數,從所有的構造函數中獲取相關構造函數

③. 內容獲取類的方法

Class clz = Class.forName("Human");
----------
public static void method1_getMethods() {
        if (clz != null) {
            System.out.println("getMethods()獲取該類的方法:");
            Method[] methods = clz.getMethods();
            for (Method method : methods) {
                System.out.println(Modifier.toString(method.getModifiers()) + " " + method.getReturnType() + " "
                        + method.getName());
            }
        }
    }
----------
public static void method2_getDeclaredMethods() {
        System.out.println("getDeclaredMethods()獲取該類的方法:");
        if (clz != null) {
            Method[] declaredMethods = clz.getDeclaredMethods();
            for (Method method : declaredMethods) {
                System.out.println(Modifier.toString(method.getModifiers()) + " " + method.getReturnType() + " "
                        + method.getName());
            }
        }
    }

getMethods()返回類中所有的public屬性的方法,包括從基類繼承的public方法。
getDeclaredMethods()返回類本身聲明的方法,包括複寫的方法,不包括從基類繼承的方法 。
getMethod(name,params)根據參數從getMethods()返回的結果中篩選。
getDeclaredMethod(name,params)根據參數從getDeclaredMethods()返回的結果中篩選 。

④. 內容獲取類的方法

Class clz = Class.forName("Human");
----------
public static void method1_getFields() {
        if (clz != null) {
            System.out.println("getFields方法獲取字段:");
            Field[] fields = clz.getFields();
            for (Field field : fields) {
                System.out.println(Modifier.toString(field.getModifiers()) + " " + field.getName());
            }
        }
    }
----------
public static void method2_getDeclaredFields() {
        if (clz != null) {
            System.out.println("getDeclaredFields方法獲取字段:");
            Field[] fields = clz.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(Modifier.toString(field.getModifiers()) + " " + field.getName());
            }
        }
    }

五、藉助反射實例化對象

Class clz = Class.forName("Human");
----------
public static void method1_InvolveConstructorAndNewInstance(Class clz) {
        if (clz != null) {
            System.out.println("調用構造函數並生成實例對象:");
            try {
                Constructor declaredConstructor = clz.getDeclaredConstructor(int.class);
                Human newInstance = (Human) declaredConstructor.newInstance(98);
                System.out.println(newInstance);
                Method method = clz.getMethod("setName", String.class);
                Method method2 = clz.getMethod("setAge", int.class);
                method.invoke(newInstance, "ZhangYi");
                method2.invoke(newInstance, 29);
                System.out.println(newInstance);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章