對反射的理解

   要理解反射,首先得理解反射的基石-》Class類

    Person類代表人,它的實例對象就是張三,李四這樣一個個具體的人, Java程序中的各個Java類屬於同一類事物,描述這類事物的Java類名就是Class。

 Class類代表Java類,它的各個實例對象又分別對應什麼呢?

        對應各個類在內存中的字節碼,例如,Person類的字節碼,ArrayList類的字節碼,等等。
一個類被類加載器加載到內存中,佔用一片存儲空間,這個空間裏面的內容就是類的字節碼,不同的類的字節碼是不同的,所以它們在內存中的內容是不同的,這一個個的空間可分別用一個個的對象來表示,這些對象顯然具有相同的類型。

 如何得到各個字節碼對應的實例對象( Class類型)? 有三種方式可以獲得

        (1)類名.class,例如,System.class
(2)對象.getClass(),例如,new Date().getClass()
(3)Class.forName("類名"),例如,Class.forName("java.util.Date");

Java類用於描述一類事物的共性,該類事物有什麼屬性,沒有什麼屬性,至於這個屬性的值是什麼,則是由這個類的實例對象來確定的,不同的實例對象有不同的屬性值。Java程序中的各個Java類,它們是否屬於同一類事物,是不是可以用一個類來描述這類事物呢?這個類的名字就是Class,要注意與小寫class關鍵字的區別。Class類描述了哪些方面的信息呢?類的名字,類的訪問屬性,類所屬於的包名,字段名稱的列表、方法名稱的列表,等等。學習反射,首先就要明白Class這個類。寫如下代碼進行對比理解:
/*Person p1 = new Person("zhangsan");
Person p2 = new Person("lisi");
*/
/*Class x1 = Vector類在內存裏的字節碼
Class x2 = Date類在內存裏的字節碼*/
Class x1 = Vector.class;
Class x2 = Date.class;


每個java類都是Class的一個實例對象,它們的內容不同,但是,它們的特徵相同,譬如,都有方法,有字段,有父類,有包。
 多個類的字節碼裝載入內存,在內存中加入一個個方塊空間表示字節碼,然後用一個個橢圓表示以這個字節碼創建出來的實例對象,並用監視代碼來說明字節碼只被裝載一次,而它構造的實例對象的構造方法被調用了多次。用如下代碼更進一步說明Class的實例是什麼?是一份字節碼,一個類在虛擬機中通常只有一份字節碼:
Date d1 = new Date();
Class clazz1 = d1.getClass();
Class clazz2 = Date.class;
Class clazz3 = null;
clazz3 = Class.forName("java.util.Date");

if(clazz1==clazz2)
{
System.out.println(clazz1.getName());
}
if(clazz1==clazz3)
{
System.out.println(clazz1.getName());
}
一個奇怪的問題:加載了字節碼,並調用了其getMethods之類的方法,但是沒有看到類的靜態代碼塊被執行,只有在第一個實例對象被創建時,這個靜態代碼纔會被執行。準確的說,靜態代碼塊不是在類加載時被調用的,而是第一個實例對象被創建時才執行的。


反射就是把Java類中的各種成分映射成相應的java類。例如,一個Java類中用一個Class類的對象來表示,一個類中的組成部分:成員變量,方法,構造方法,包等等信息也用一個個的Java類來表示,就像汽車是一個類,汽車中的發動機,變速箱等等也是一個個的類。表示java類的Class類顯然要提供一系列的方法,來獲得其中的變量,方法,構造方法,修飾符,包等信息,這些信息就是用相應類的實例對象來表示,它們是Field、Method、Contructor、Package等等。 


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