當咱們爲某個項目配置好jdk後,java文件在進行編譯時,javac就已經將對應的Java文件編譯爲class文件了。在java中建立這個類的對象時且該類是首次被加載時,jvm虛擬機就加載對應的class文件並在內存中(方法區)建立了這個類對象並拷貝這個class文件中全部的成員變量到這個class類對象。 以後在堆內存中開闢一塊內存空間用於存儲這個類的對象並拷貝一份屬性,棧中存放的是堆中對應的類的對象的內存地址。過程見下圖: java
反射:經過建立對象實例加載class文件到jvm上面時建立的Class對象來獲取這個類中的成員變量。其實就是平時咱們獲取這個類的信息是經過實例這個類來獲取,而反射就是經過class類對象來獲取信息jvm
咱們以代碼爲例: 先建立一個用於反射的對象類:函數
public class Student { public Student(){ System.out.println("無參構造"); } public Student(int i){ System.out.println("一個參數構造函數"); } private Student(int i,String name){ System.out.println("兩個參數構造函數");
} private String name; private String sex; private String age; public Date bir;this
public Date getBir() { return bir; } public void setBir(Date bir) { this.bir = bir; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } private String getAge() { return age; } private void setAge(String age) { this.age = age; } }3d
反射操做: public class test {code
@Test//經過反射獲取成員變量 public void reflectForBianliang() throws Exception{ //咱們是能夠經過反射來獲取或者設置類對象中的變量的 //建立一個類對象 Class cla=Student.class; //建立用類對象建立一個實例對象(這個方法會調用無參構造) //此處能夠引出一個問題,就是爲何類中必須有一個無參構造函數,就是由於newInstance()方法實例化時調用的就是無參構造。 Object obj=cla.newInstance(); //獲取類對象中的某個變量 Field fie=cla.getDeclaredField("age"); //開啓權限,不然沒法設置私有變量 fie.setAccessible(true); //賦值 fie.set(obj, "18"); //取值 Object value=fie.get(obj); System.out.println(value); } @Test public void reflectForfangfa() throws Exception{ //經過反射能夠調用方法 Class cla=Student.class; Object obj=cla.newInstance(); //獲取類對象中的某個方法(getAge) Method method=cla.getDeclaredMethod("setAge", String.class); //由於是私有的因此開啓權限才能夠調用 method.setAccessible(true); method.invoke(obj, "18"); //獲取類中的getAge方法 Method method2=cla.getDeclaredMethod("getAge"); method2.setAccessible(true); Object obj2=method2.invoke(obj); System.out.println(obj2); } } 以上有什麼疏漏或者錯誤,歡迎各位批評指正。