一探橱、什么是反射
在運(yùn)行狀態(tài)中,對(duì)于 任意一個(gè)類(lèi)糠赦,都能夠獲取到這個(gè)類(lèi)的所有屬性和方法梦谜;對(duì)于 任意一個(gè)對(duì)象滴肿,都能夠調(diào)用它的任意一個(gè)方法和屬性感帅,這種動(dòng)態(tài)獲取信息以及調(diào)用對(duì)象方法的功能就稱(chēng)為Java
的反射機(jī)制廊散。
要使用反射機(jī)制枣购,就必須先獲取到該類(lèi)的 字節(jié)碼文件對(duì)象 娶耍,通過(guò)字節(jié)碼文件對(duì)象免姿,能夠通過(guò)該類(lèi)中的方法獲取到我們需要的所有信息。
當(dāng)類(lèi)加載的時(shí)候榕酒,會(huì)將.class
文件讀入內(nèi)存胚膊,并為它創(chuàng)建一個(gè)Class
對(duì)象,它包含了所有相關(guān)的信息想鹰,也就是上面所說(shuō)的 字節(jié)碼文件對(duì)象紊婉。
二、獲取 Class 對(duì)象的方法
- 通過(guò)
Class
類(lèi)的靜態(tài)方法杖挣,此時(shí)該類(lèi)還是處于 源文件階段肩榕。
Class clazz1 = Class.forName("限定名");
- 當(dāng)類(lèi)被加載成
.class
文件時(shí),此時(shí)Clazz
類(lèi)變成了.class
惩妇,在獲取該字節(jié)碼文件對(duì)象株汉,也就是獲取自己,該類(lèi)處于 字節(jié)碼階段歌殃。
Class clazz2 = Clazz.class;
- 通過(guò)類(lèi)的實(shí)例獲取該類(lèi)的字節(jié)碼文件對(duì)象乔妈,該類(lèi)處于 創(chuàng)建對(duì)象階段。
Class clazz3 = p.getClass();
三氓皱、使用反射
在我們使用反射的時(shí)候會(huì)涉及到三個(gè)方面:構(gòu)造函數(shù)路召、屬性和方法,以下面這個(gè)類(lèi)為例波材。
/**
* @author lizejun
**/
public class ReflectHolder {
public String openValue;
private String closeValue;
private ReflectHolder() {}
public ReflectHolder(String openValue, String closeValue) {
this.openValue = openValue;
this.closeValue = closeValue;
}
public void setOpenValue(String openValue) {
this.openValue = openValue;
}
private void setCloseValue(String closeValue) {
this.closeValue = closeValue;
}
}
3.1 構(gòu)造函數(shù)
通過(guò)Class
類(lèi)獲取構(gòu)造方法股淡,有以下四類(lèi):
-
Constructor[] - getConstructors()
:所有public
構(gòu)造方法。 -
Constructor[] - getDeclaredConstructors()
:所有構(gòu)造方法廷区,包括public
唯灵、protected
、private
隙轻、默認(rèn)埠帕。 -
Constructor - getConstructor(null)
:無(wú)參構(gòu)造方法。 -
Constructor - getDeclaredConstructor(x.class)
:參數(shù)為x
的構(gòu)造方法玖绿。
通過(guò)其中一種方法敛瓷,我們可以獲取到Constrcutor
對(duì)象,并通過(guò)該對(duì)象來(lái)創(chuàng)建實(shí)例:
-
newInstance(Object... args)
:使用此Constructor
對(duì)象表示的構(gòu)造方法來(lái)創(chuàng)建其對(duì)應(yīng)類(lèi)的實(shí)例斑匪,并用指定的參數(shù)args
初始化該實(shí)例呐籽。
3.2 屬性
-
Field[] - getFields()
:所有public
屬性。 -
Field[] - getDeclaredFields()
:所有屬性。 -
Field - getField(屬性名稱(chēng))
:獲取對(duì)應(yīng)名稱(chēng)的Field
绝淡。
獲取到Field
對(duì)象后宙刘,可以通過(guò)Field.set(obj, value)
方法苍姜,設(shè)置obj
對(duì)象的對(duì)應(yīng)屬性值為value
牢酵。
對(duì)于非public
屬性,需要先調(diào)用Field. setAccessible(true)
解除私有規(guī)定衙猪。
3.3 方法
-
Method[] - getMethods()
:所有public
方法馍乙。 -
Method[] - getDeclaredMethods()
:所有方法。 -
Method - getMethod("方法名", a.class, b.class, ...)
:通過(guò)方法名和形參列表.class
這兩項(xiàng)來(lái)唯一確定方法垫释。
獲取到Method
對(duì)象后丝格,可以通過(guò)Method.invoke(obj, 實(shí)參列表)
來(lái)調(diào)用該方法,其返回值就為該方法的返回值棵譬,需要進(jìn)行類(lèi)型強(qiáng)制轉(zhuǎn)換显蝌。
對(duì)于不可訪(fǎng)問(wèn)的方法,需要先調(diào)用Method.setAccessible(true)
解除私有規(guī)定订咸。