反射


一、概念

  1.反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法。

  2.反射可以在一個類運行的時候獲取類的信息的機制,可以獲取在編譯期不可能獲得的類的信息。

  3.對於任意一個對象,都能調用它的任意一個方法和屬性(private:落魄了,家人們)。

  4.因為類的信息是保存在Class對象中的,而這個Class對象是在程序運行時被類加載器(ClassLoader)動態加載的。

  5.當類加載器裝載運行了類后,動態獲取Class對象的信息以及動態操作Class對象的屬性和方法的功能稱為Java語音的反射機制。

二、作用

  1.反編譯:.class —> .java。

  2.通過反射機制訪問Java對象中的屬性、方法、構造方法等。

三、原理

  利用加載到jvm中的.class文件來進行操作,.class文件中包含java類的所有信息,當你不知道某個類具體信息時,可以使用反射獲取class,然后進行各種操作。

  在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。

  總結說:反射就是把java類中的各種成分映射成一個個的Java對象,並且可以進行操作。

四、獲取class的三種方法

            List<Class> classList=new ArrayList<Class>();
            //獲取class的三種方式
            //1.通過對象調用getClass()方法獲取
            classList.add(human.getClass());
            //2.通過類名.class獲取(ps:所有類都有一個隱含的靜態的成員變量class)。首選方法,安全可靠性能高
            classList.add(Human.class);

            //3.通過CLass類的靜態方法forName()獲取,注意該方法可能拋出ClassNotFound異常
            classList.add(Class.forName("reflex.Human"));

            System.out.println(classList.toString());

 

五、Class類的主要方法

  getName():獲得類的完整名字。

  getFields():獲得類的public類型的屬性。

  getDeclaredFields():獲得類的所有屬性。包括private 聲明的和繼承類

  getMethods():獲得類的public類型的方法。

  getDeclaredMethods():獲得類的所有方法。包括private 聲明的和繼承類

  getMethod(String name, Class[] parameterTypes):獲得類的特定方法,name參數指定方法的名字,parameterTypes 參數指定方法的參數類型。

  getConstructors():獲得類的public類型的構造方法。

  getConstructor(Class[] parameterTypes):獲得類的特定構造方法,parameterTypes 參數指定構造方法的參數類型。

  newInstance():通過類的構造方法創建這個類的一個對象。

六、實例

public class Human {
    public String name;
    private int age=18;
    public static String text="---static text---";

    public int getAge() {
        return age;
    }

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

    void human(){
    }

    private void fly(){
        System.out.println("can not fly");
    }

    public void hello(){
        System.out.println("hello");
    }

}
public class ReflexTest {
    public static void main(String[] args) {
        System.out.println(Human.text);
        Human human=new Human();
        try {
            List<Class> classList=new ArrayList<Class>();
            //獲取class的三種方式
            //1.通過對象調用getClass()方法獲取
            classList.add(human.getClass());
            //2.通過類名.class獲取(ps:所有類都有一個隱含的靜態的成員變量class)。首選方法,安全可靠性能高
            classList.add(Human.class);

            //3.通過CLass類的靜態方法forName()獲取,注意該方法可能拋出ClassNotFound異常
            classList.add(Class.forName("reflex.Human"));

            System.out.println(classList.toString());

            System.out.println(classList.get(1).getName());

            System.out.println("private:落魄了,家人們");
            Field field=classList.get(1).getDeclaredField("age");
            System.out.println(field);
            System.out.println(human.getAge());
            //設置可訪問private
            field.setAccessible(true);

            //設置private變量的值
            field.set(human,100);
            System.out.println(human.getAge());

            Method privateMethod =classList.get(1).getDeclaredMethod("fly",null);
            privateMethod.setAccessible(true);
            privateMethod.invoke(human,null);

            System.out.println("------getFields:");
            //getFields()獲取public類型的成員變量
            Field[] fieldsOfPublic=classList.get(1).getFields();
            for (Field i:fieldsOfPublic) {
                System.out.println(i);
            }
            System.out.println("------getDeclaredFields:");
            //getDeclaredFields()獲取所有成員變量
            Field[] fieldsAll = classList.get(1).getDeclaredFields();
            for (Field j:fieldsAll) {
                System.out.println(j);
            }

            //getMethod(name,paramterTypes)只能獲取public類型的成員方法
            Method method=classList.get(1).getMethod("hello",null);
            System.out.println("獲取成員方法hello--"+method);

            //getDeclaredMethods()獲取所有成員方法
            Method[] methods=classList.get(1).getDeclaredMethods();
            System.out.println("所有成員方法");
            for (Method m:methods) {
                System.out.println(m);
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

 參考:

  https://blog.csdn.net/qq_24549805/article/details/104013083

  https://blog.csdn.net/huangliniqng/article/details/88554510


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM