Java--反射機制初探

好多天沒寫博客 項目剛剛上線 來寫一寫deom 昨晚複習了一下java的反射機制 寫了一個小deom複習下反射機制 代碼這東西還是寫出來比較爽呀
廢話不多說
反射:Java反射機制容許程序在運行時加載、探知、使用編譯期間完全未知的classes。
也就是說,Java可以加載一個運行時才得知名稱的class,獲得其完整結構。
這個完整結構是說我們可以通過反射得到裏面的任何東西,不管是不是私有的,打破了private,public,protected的各種限制,動態的得到類中的方法
利用反射的步驟以及方法:
第一步:首先得到class文件,可以通過三種方式獲得,第一種的Class.forName(“Class”),第二種是通過先new出來一個對象,通過對象去調用自己的class方法,第三種是直接通過類.class方法,都可以得到
第二步:可以通過已經獲得的class文件,獲得屬性,方法,構造函數的方法
第三步:可以選擇暴力破解setAccessible(),不然有些private無法得到,然後可以進行逆想做的操作
接下來不說什麼,上代碼:
首先是測試類Student


public class Student {

    private int age;
    private String name;
    public Student() {

    }
    public Student(int age,String name) {
        // TODO Auto-generated constructor stub
        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;
    }

    public void testPrint(){
        System.out.println("===============通過反射實例化=====================");
    }

}

測試Deom

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Reflect {

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        // 第一步 獲得得到反射類的方法 有三種
        // 第一種 通過Class.forName(); 第二種 通過getClass 第三種 直接通過類調用.class方法
        Class c1 = Class.forName("Student");
        Class c2 = Student.class;
        Student s1 = new Student();
        Class c3 = s1.getClass();
        /**
         * 當得到class 文件 也就是字節碼文件後 便可以得到裏面的所有內容,
         * 有兩個吸引的地方,一個就是動態加載,一個是可以獲得裏面所有的內容,而不是通過子類或者new出一個對象
         * 是直接的得到裏面的任何東西,不管是public或者是private或者是hide隱藏的方法
         */
        // 第二步 當得到字節碼文件之後 可以實例化這個類的對象
        Student student = (Student) c1.newInstance();
        student.testPrint();
        /**
         * 此時輸出的結果是 ===============通過反射實例化===================== 也就意味着 如果是實例化
         * 會直接執行無參構造方法
         */
        // 第三步 可以避免構造對象 得到class類中的屬性field constructor 構造函數 方法 method
        /**
         * Field 字段 可以獲得所有類中的屬性 通過getDeclaredFields或者是getFields的方法
         * 前者可以獲得的是本類的屬性,包含private 後者獲得的是本類以及父類的不包含priate屬性
         */
        Field[] fs = c1.getDeclaredFields();
        // 定義可變長的字符串,用來存儲屬性
        StringBuffer sb = new StringBuffer();
        // 通過追加的方法,將每個屬性拼接到此字符串中
        // 最外邊的public定義
        sb.append(Modifier.toString(c1.getModifiers()) + " class "
                + c1.getSimpleName() + "{\n");
        // 裏邊的每一個屬性
        for (Field field : fs) {
            sb.append("\t");// 空格
            sb.append(Modifier.toString(field.getModifiers()) + " ");// 獲得屬性的修飾符,例如public,static等等
            sb.append(field.getType().getSimpleName() + " ");// 屬性的類型的名字
            sb.append(field.getName() + ";\n");// 屬性的名字+回車
        }
        sb.append("}");
        System.out.println(sb);
        /**
         * 每個field可以拿出來 然後通過setAccessible(true)讓private方法進行破解,從而進行設置,繞過對象得到
         */
        Field age = c1.getDeclaredField("age");
        age.setAccessible(true);// 我可以稱之爲暴力破解麼
        age.set(student, 10);
        System.out.println(student.getAge());// 此時的輸出是10 是不是感覺很神奇 哈哈哈哈
    }
    /**
     * 其他的構造函數 方法等都是類似的步驟 注意: 最好是通過setAccessible()的方法進行暴力破解 不然如果是private的會報異常
     * 得到method之後,需要involve一下
     */

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