- Java程序員面試筆試寶典(第2版)
- 何昊等編著
- 1201字
- 2022-06-17 16:00:41
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é)果為:

- iOS面試一戰(zhàn)到底
- 數(shù)據(jù)庫程序員面試筆試真題與解析
- Objective-C應(yīng)用開發(fā)全程實錄
- Learning ArcGIS Pro 2
- 控糖控脂健康餐
- Magento 2 Development Cookbook
- ASP.NET 3.5程序設(shè)計與項目實踐
- 量化金融R語言高級教程
- QGIS By Example
- PHP 7+MySQL 8動態(tài)網(wǎng)站開發(fā)從入門到精通(視頻教學(xué)版)
- The Professional ScrumMaster’s Handbook
- App Inventor創(chuàng)意趣味編程進階
- 后臺開發(fā):核心技術(shù)與應(yīng)用實踐
- Scala編程實戰(zhàn)
- Learning Ionic