java反射(reflex)

 

java反射  reflex  反射獲取方法  反射獲取屬性

一、反射概念:

      1、一定是在運行狀態中進行的

      2、對於任意一個實體類,都能夠知道這個類的所有屬性和方法

      3、對於任意一個對象,都能夠調用它的任意方法和屬性

     這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制

二、利用反射我們能做什麼

     1、在運行時判斷任意一個對象所屬的類

     2、在運行時構造任意一個類的對象

    3、在運行時判斷任意一個類所具有的成員變量和方法

    4、在運行時調用任意一個對象的方法

    5、生成動態代理

三、獲取class對象

    三種方法

    1、Class.forname(全類名) (帶異常處理 推薦使用)

//獲取該對象的class
Class c3 = null;
try {
    c3 = Class.forName("com.test.Student");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
//打印獲取的類名稱
System.out.println("類名稱:"+c3.getName());

2、類名.Class

/獲取該對象的class
Class c2 = Person.class;
//打印獲取的類名稱
System.out.println("類名稱:"+c2.getName());

3、對象.getclass()

//獲取該對象的class
Class c1 = person.getClass();
//打印獲取的類名稱
System.out.println("類名稱:"+c1.getName());

注意凡是反射必須是Class

 

四、反射獲取方法

   1、第一步獲取反射接口

//1、先獲取反射的Class
Class<?> stuClass = null;
try {
    stuClass = Class.forName("com.test.Student");
    System.out.println(stuClass);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

   2、獲取方法

       分2種

      ①獲取所有的公共方法 本類以及父類中以及接口中所有的公共方法,符合訪問修飾符規律 public的方法 private不行

      ②獲取當前類的所有方法(1.忽略訪問修飾符規律 2.只限當前類,不含父類)

    //2、獲取方法
    // 1)獲取所有的公共方法   本類以及父類中以及接口中所有的方法,2.符合訪問修飾符規律 public的方法 private不行
        Method[] methods = stuClass.getMethods();
        for (Method method : methods) {
            System.out.println("獲取所有的方法:" + method);
        }
        // 2)獲取當前類的所有方法(1.忽略訪問修飾符規律 2.只限當前類)
        Method[] methods1 = stuClass.getDeclaredMethods();
        for (Method method : methods1) {
            System.out.println("獲取當前類的方法:" + method);
        }

五、反射獲取屬性

     分2種

     1、首先,依舊要獲取class

Class<?> stuClass = null;
try {
   stuClass = Class.forName("com.test.Student");
   System.out.println(stuClass);
} catch (ClassNotFoundException e) {
   e.printStackTrace();
}

     2、反射獲取屬性

        也分2種

       ①所有的公共屬性 本類及其父類中的

       ②本類中的屬性

        //2、獲取屬性
        // 1)所有的公共屬性  本類及其父類中的
        Field[] fields = stuClass.getFields();
        for (Field field : fields) {
            System.out.println("所有的公共public屬性:" + field);
        }

        //  2)本類中的屬性
        Field[] fields1 = stuClass.getDeclaredFields();
        for (Field field : fields1) {
            System.out.println("本類中的屬性:" + field);
        }

六、反射操作屬性     

    方法一:

    1、首先獲取Class對象

    2、在獲取Object對象

    3、在Object對象轉爲實例

    4、設置實例的屬性

   上代碼

       //1、先獲取反射的Class
        Class<?> stuClass = null;
        try {
            stuClass = Class.forName("com.test.Student");
            System.out.println(stuClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //方法一
        // 1)獲取對象
        Object instance = null;
        try {
            instance = stuClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        //2)、轉化爲實例
        Student stud = (Student)instance;
        //3)、設置實例的屬性
        stud.setStuNum("10001");
        stud.setName("張三");

        System.out.println("1、重新設置的屬性   姓名:"+stud.getName()+"  學號:"+stud.getStuNum());

  方法二:

    1、首先獲取Class對象

    2、反射獲取屬性

    3、反射方法設置屬性值

       //1、先獲取反射的Class
        Class<?> stuClass = null;
        try {
            stuClass = Class.forName("com.test.Student");
            System.out.println(stuClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }       
        Field stuNumField = null;
        Field stuClassNameField = null;
        Field stuGradeField = null;
        try {
            //2、反射獲取屬性
            stuNumField = stuClass.getDeclaredField("stuNum");    // private 屬性
            stuClassNameField = stuClass.getDeclaredField("className");  // private 屬性
            stuGradeField = stuClass.getDeclaredField("grade");   // public 屬性
            //操作私有屬性  一定要 設置 爲true   public屬性則不需  否則報錯
            stuNumField.setAccessible(true);
            stuClassNameField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            //3、給屬性賦值
            stuNumField.set(stud,"10002");  //相當於stud.setStuNum("10002");
            stuClassNameField.set(stud,"計算機班");
            stuGradeField.set(stud,"一年級");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println("2、重新設置的屬性   班級:"+stud.getClassName()+"  學號:"+stud.getStuNum()+"  年級:"+stud.getGrade());

注意:操作私有屬性   setAccessible 方法一定要 設置 爲true,   public屬性則不需 否則報錯

 

七、反射操作實例的方法

   步驟:

    1、先獲取反射的Class

    2、獲取需要操作的方法

    3、setAccessible 設置爲可利用 不然會報錯,public方法則不需

    4、獲取實例對象

    5、調用該方法

    奉上代碼:

   

 

        //1、先獲取反射的Class
        Class<?> stuClass = null;
        try {
            stuClass = Class.forName("com.test.Student");
            System.out.println(stuClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method method = null;
        try {
           //2、獲取方法
            method = stuClass.getDeclaredMethod("setStuNum",String.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //3、設置爲可利用  不然會報錯
        method.setAccessible(true);

        Student person = null;//將instance轉化爲Person
        try {
            //4、獲取實例對象
            person = (Student)stuClass.newInstance();
            //5、調用該方法
            method.invoke(person,"10003");
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }catch (InvocationTargetException e) {
            e.printStackTrace();
        }
八、反射操作構造方法(構造方法分public和 private)

     步驟:

    1、先獲取反射的Class

    2、獲取需要構造方法(分無參數和有參數 2種)

    3、調用構造方法(無參數和有參數 2種)

   上代碼:

        //1、先獲取反射的Class
        Class<?> stuClass = null;
        try {
            stuClass = Class.forName("com.test.Student");
            System.out.println(stuClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //獲取全部公共構造方法 public
        Constructor<?>[] constructors = stuClass.getConstructors();
        for (Constructor constructor:constructors) {
            System.out.println("全部公共構造方法"+constructor);
        }
        //2、獲取本類的公共構造方法
        Constructor<?>[] constructors02 = stuClass.getDeclaredConstructors();
        for (Constructor constructor:constructors02) {
            System.out.println("本類構造方法" + constructor);
        }

        try {
            //3-1獲取指定  無參數的構造方法
            Constructor<?> constructor02 = stuClass.getConstructor();
            Student stud = null;
            try {
                //如果構造函數是private  一定要加入下面這句話  否則報錯
                //constructor02.setAccessible(true);
                stud = (Student) constructor02.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            System.out.println("本類無參數構造方法的對象:"+stud);


            //3-2獲取指定  有參數的構造方法
            Constructor<?> constructor03 = stuClass.getConstructor(String.class);
            Student stud2 = null;//轉化爲Person類
            try {

                //如果構造函數是private  一定要加入下面這句話  否則報錯
                //constructor02.setAccessible(true);
                constructor03.setAccessible(true);
                //4 調用構造方法 傳參
                stud2 = (Student)constructor03.newInstance("10004");
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            System.out.println("本類指定的有參數的構造方法的對象:"+stud2);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

   九、使用反射給對象賦值通用方法

    //動態給對象賦值
    public void setProperty(Object obj, String propertyName, Object value) throws 
    NoSuchFieldException, IllegalAccessException {
        Class<?> perclass = obj.getClass();
        Field field = perclass.getDeclaredField( propertyName);//獲得屬性
        field.setAccessible(true);//因爲是私有的
        field.set(obj,value);//(對象,方法)
    }

  調用

        //使用反射給對象賦值通用方法
        Student student = new Student();
        try {
            test.setProperty(student,"stuNum","10007");
            System.out.println("動態設置的屬性爲:stuNum="+student.getStuNum());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

 

發佈了27 篇原創文章 · 獲贊 5 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章