官术网_书友最值得收藏!

1.4 反射

在Java語言中,反射機制是指對于處在運行狀態(tài)中的類,都能夠獲取到這個類的所有屬性和方法。對于任意一個對象,都能夠調(diào)用它的任意一個方法以及訪問它的屬性;這種通過動態(tài)獲取類或?qū)ο蟮膶傩砸约胺椒◤亩瓿烧{(diào)用功能被稱為Java語言的反射機制。它主要實現(xiàn)了以下功能:

? 獲取類的訪問修飾符、方法、屬性以及父類信息。

? 在運行時根據(jù)類的名字創(chuàng)建對象。可以在運行時調(diào)用任意一個對象的方法。

? 在運行時判斷一個對象屬于哪個類。

? 生成動態(tài)代理。

在反射機制中Class是一個非常重要的類,在Java語言中獲取Class對象主要有如下幾種方法。

1)通過className.class來獲取:

程序的運行結(jié)果為:

2)通過Class.forName()來獲取:

程序的運行結(jié)果為:

3)通過Object.getClass()來獲取:

程序的運行結(jié)果為:

從上面的例子可知,雖然這三種方式都可以獲得類的Class對象,但是它們還是有區(qū)別的,主要區(qū)別如下所示:

? 方法1)不執(zhí)行靜態(tài)塊和動態(tài)構(gòu)造塊;

? 方法2)只執(zhí)行靜態(tài)塊,而不執(zhí)行動態(tài)構(gòu)造塊;

? 方法3)因為需要創(chuàng)建對象,所以會執(zhí)行靜態(tài)塊和動態(tài)構(gòu)造塊。

Class類提供了非常多的方法,下面給出三類常用的方法。

(1)獲取類的構(gòu)造方法

構(gòu)造方法的封裝類為Constructor,Class類中有如下四個方法來獲得Constructor對象:

1)public Constructor<?>[] getConstructors():返回類的所有的public構(gòu)造方法;

2)public Constructor<T>getConstructor(Class<?>... parameterTypes):返回指定的public構(gòu)造方法;

3)public Constructor<?>[] getDeclaredConstructors():返回類的所有的構(gòu)造方法;

4)public Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes):返回指定的構(gòu)造方法。

(2)獲取類的成員變量的方法

成員變量的封裝類為Field類,Class類提供了以下四個方法來獲取Field對象:

1)public Field[] getFields():獲取類的所有public成員變量;

2)public Field getField(String name):獲取指定的public成員變量;

3)public Field[] getDeclaredFields():獲取類的所有成員變量;

4)public Field getDeclaredField(String name):獲取任意訪問權(quán)限的指定名字的成員變量。

(3)獲取類的方法

1)public Method[] getMethods();

2)public Method getMethod(String name,Class<?>... parameterTypes) public Method[];

3)getDeclaredMethods():獲取所有的方法;

4)public Method getDeclaredMethod(String name,Class<?>... parameterTypes)。

使用示例如下所示:

程序的運行結(jié)果為:

引申:有如下代碼:

現(xiàn)給定一個ReadOnlyClass的對象roc,能否把這個對象的age值改成30?

答案:從正常編程的角度出發(fā)分析,會發(fā)現(xiàn)在本題中,age屬性被修飾為private,而且這個類只提供了獲取age的public的方法,而沒有提供修改age的方法,因此,這個類是一個只讀的類,無法修改age的值。但是Java語言還有一個非常強大的特性:反射機制,所以本題中,可以通過反射機制來修改age的值。

在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取對象的信息以及動態(tài)調(diào)用對象的方法的功能稱為Java語言的反射機制。Java反射機制允許程序在運行時加載、探知和使用編譯期間完全未知的class。換句話說,Java可以加載一個運行時才得知名稱的class,獲得其完整結(jié)構(gòu)。

在Java語言中,任何一個類都可以得到對應(yīng)的Class實例,通過Class實例就可以獲取類或?qū)ο蟮乃行畔ⅲ▽傩裕‵ield對象)、方法(Method對象)或構(gòu)造方法(Constructor對象)。對于本題而言,在獲取到ReadOnlyClass類的Class實例以后,就可以通過反射機制獲取到age屬性對應(yīng)的Field對象,然后可以通過這個對象來修改age的值,實現(xiàn)代碼如下所示:

程序的運行結(jié)果為:

主站蜘蛛池模板: 宾川县| 西乌珠穆沁旗| 孟连| 镇雄县| 寿光市| 延庆县| 城口县| 丹阳市| 临沧市| 晋中市| 仁寿县| 右玉县| 个旧市| 民和| 龙岩市| 建始县| 盐津县| 甘孜县| 安宁市| 玉溪市| 阿克苏市| 山西省| 钟祥市| 隆安县| 昭平县| 安阳市| 辽中县| 庆城县| 桂东县| 云霄县| 温宿县| 德江县| 吉林市| 曲麻莱县| 保亭| 上饶市| 礼泉县| 通河县| 志丹县| 桃江县| 秀山|