能夠分析類能力的程序稱為反射(reflective)瓣窄,反射機制可以用來:
- 在運行時分析類的能力。
- 在運行時查看對象维费,例如怔毛,編寫一個toString方法供所有類使用员萍。
- 實現(xiàn)通用的數(shù)組操作代碼。
- 利用Method對象拣度,這個對象很像C++中的函數(shù)指針碎绎。
1. Class類
- 一個Class類對象表示一個特定類的屬性。在程序運行期間抗果,Java運行時系統(tǒng)始終為所有的對象維護一個被稱為運行時的類型標(biāo)識筋帖,虛擬機利用運行時類信息選擇相應(yīng)的方法執(zhí)行。
- 獲得類名對應(yīng)的Class對象
String className = "java.util.Random";
Class cl = Class.forName(className); //調(diào)用Class的靜態(tài)方法
- Class對象實際上表示的是一個類型冤馏,而這個類型可以是int日麸,即int.Class也是一個Class對象。
- Class實際上是一個泛型類逮光。
- 實現(xiàn)兩個類對象的比較代箭,利用
==
運算符
if(employ.getClass() == Employee.class){...}
- 動態(tài)創(chuàng)建一個類實例
String s = "java.util.Random"
Object m = Class.forName(s).newInstance(); //class.newInstance()方法
2. 利用反射分析類的能力
- java.lang.reflect包中有三個類Field、Method和Constructor分別用于描述類的域涕刚、方法和構(gòu)造器
- Field嗡综、Method和Constructor這三個類中具有如下方法
-
String getName()
返回一個用于描述構(gòu)造器、方法或域名的字符串杜漠。 -
int getModifiers()
返回一個用于描述構(gòu)造器极景、方法或域的修飾符的整型數(shù)值,使用Modifier.isPublic(int i)等方法可以分析這個返回值碑幅。 -
Class getDeclaringClass()
返回一個用于描述構(gòu)造器、方法或域的Class對象塞绿。 -
Class getReturnType()
(僅在Method類中)沟涨,返回方法的返回類型的Class -
Class[] getParameterTypes()
(僅在Constructor和Method類中),返回一個用于描述參數(shù)類型的Class對象數(shù)組异吻。
- Class類中的方法
-
Field[] getFields()
返回這個類或其超類的公有域裹赴。 -
Field[] getDeclaredFields()
返回類的全部域。這兩個方法诀浪,如果類中沒有域或者是基本類型或是數(shù)組類型棋返,兩個方法返回長度為0的數(shù)組。 -
Method[] getMethods()
返回所有的公有方法雷猪,包括超類的方法睛竣。 -
Method[] getDeclaredMethods()
返回類或接口中所有方法,但不包括超類繼承的方法求摇。 -
Constructor[] getConstructors()
返回公有構(gòu)造器射沟。 -
Constructor[] getDeclaredConstructors()
返回所有構(gòu)造器殊者。
3. 在運行時使用反射分析對象
- 獲取類中某個域的值,如:
Employee harry = new Employee("Harry Hacker", 3500, 10, 1, 1989);
Class cl = harry.getClass();
Field field = cl.getDeclaredField("name");
Object v = field.get(harry); //v應(yīng)該是String類的對象"Harry Hacker"
field.set(harry, "Amy"); //harry對象的name被改為"Amy"
- 覆蓋訪問控制setAccessible(boolean)
field.setAccessible(true); //若該域是private的验夯,設(shè)置為true之后則可以訪問
field.isAccessiable() //返回反射對象的可訪問標(biāo)志的值
- Class類
Field getField(String name)
Field[] getField()
返回指定名稱的公有域猖吴,或包含所有域的數(shù)組。
3. 使用反射編寫泛型數(shù)組代碼
- 整數(shù)類型int[]可以被轉(zhuǎn)換成Object挥转,但不能轉(zhuǎn)換成對象數(shù)組Object[]海蔽。
- 返回一個具有給定類型、給定維數(shù)的新數(shù)組
static Object newInstance(Class componentType, int length);
static Object newInstance(Class componentType, int[] lengths);
4. 調(diào)用任意方法
- Class獲得指定方法
Method getMethod(String name, Class... parameters);
- Method調(diào)用該方法
pubilc Object invoke(Object implicitParameter, Object... explicitParameters);
第一個參數(shù)是隱式參數(shù)绑谣,其余的參數(shù)提供了顯示參數(shù)(沒有顯示傳參就傳遞一個null)党窜,對于靜態(tài)方法,第一個參數(shù)可以忽略設(shè)置為null域仇。