好多天沒寫博客 項目剛剛上線 來寫一寫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一下
*/
}