Java 反射(Class class相關)

>Class類:反射的根源

>1.Object class,是所有的Java classes的繼承根源,

其內聲明瞭數個應該在所有Java class中被改寫methods:hashCode()、equals()、clone()、toString()、getClass()等。

其中getClass()返回了一個 Class object

>2.小插曲:爲什麼重寫hashCode()和重寫eauqls()要同時進行?

>3.Class class

  • Class class十分特殊。它和一般classes一樣繼承自Object,其實體用以表達Java程序運行時的classes和interfaces,也用來表達enum、array、primitive Java types(8個)
  • (boolean, byte, char, short, int, long, float, double)以及關鍵詞void
  • 當一個class被加載,或當加載器(class loader)的defineClass()被JVM調用,JVM 便自動產生一個Class object。如果想借由“修改Java標準庫源碼”來觀察Class object的實際生成時機(例如在Class的constructor內添加一個println())不能夠!因爲Class並沒有public constructor
  • 換句話說,不能new!Class是通過Java虛擬機通過內部機制new出來實例,並且去執行的
  • Class是Reflection的起源。針對任何想要探勘的class,唯有先爲它產生一個Class object,接下來才能經由後者喚起數十多個的Reflection APIs

>4.Class 對象取得途徑:

Java允許多種方式爲一個class生成對應的Class object,不管一個Java類生成多少個對象,這些對象所對應的Class對象只有唯一的一個。

注意:

  • 調用Object class 對應的Class對象的getsuperclass()會返回null(再往上,null調用任意方法都會拋空指針異常)
  • 最後的方式,對於原生的8種類型,使用.class語法,包裝類型,使用.TYPE語法

>5.運行時生成instances

欲生成對象實體,在Reflection 動態機制中有兩種作法,一個針對“無自變量ctor”,一個針對“帶參數ctor”。如果欲調用的是“帶參數ctor“就比較麻煩些,不再調用Class的newInstance(),而是調用Constructor 的newInstance()。首先準備一個Class[]做爲ctor的參數類型(本例指定爲一個double和一個int),然後以此爲自變量調用getConstructor(),獲得一個專屬ctor。接下來再準備一個Object[] 做爲ctor實參值(本例指定3.14159和125),調用上述專屬ctor的newInstance()。

不含參數構造(省略了構造步驟):

含參數構造(先獲取相應的構造器,再用構造來生成對象,這種方式是通用的):

>6.運行時調用methods

這個動作和上述調用“帶參數之ctor”相當類似。首先準備一個Class[]做爲參數類型(本例指定其中一個是String,另一個是Hashtable),然後以此爲自變量調用getMethod(),獲得特定的Method object。接下來準備一個Object[]放置自變量,然後調用上述所得之特定Method object的invoke()。
爲什麼獲得Method object時不需指定回返類型?因爲方法重載不包含返回值,只包含名字和返回值構成方法簽名,來唯一標識一個方法。

>7.運行時變更fields內容

首先調用ClassgetField()並指定field名稱。獲得特定的Field object之後便可直接調用Fieldget()set()

最後,關於一些反射方法調用時,我們會發現傳入了某個對象的引用,這是因爲一個類可能生成多個不同的實例,當調用成員或者成員方法時,可能會得到不同的結果,所以我們必須要指定獲取哪一個對象裏的成員或者成員方法的執行。

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