一、什么是類的成員叉瘩?
眾所周知器罐,Java反射可以在運(yùn)行時(shí)獲取類的成員。那么問(wèn)題來(lái)了垒棋,什么是類的成員呢?一起來(lái)看一下Java 7給出的官方解釋:
According to The Java Language Specification, Java SE 7 Edition, the members of a class are the inherited components of the class body including fields, methods, nested classes, interfaces, and enumerated types. Since constructors are not inherited, they are not members. This differs from the implementing classes of java.lang.reflect.Member.
以上信息可以理解為:
類的成員包括:從父類繼承得到的成員變量,方法;內(nèi)嵌的類耻姥,接口,枚舉類型有咨。因?yàn)闃?gòu)造方法無(wú)法被繼承,所以不是類成員蒸健。
二座享、成員變量(field)
1. 獲取成員變量
先來(lái)看一個(gè)對(duì)Class
API中獲取成員變量方法的總結(jié)婉商。
Class API | 通過(guò)List返回多個(gè)成員變量 | 返回父類成員變量 | 返回私有成員變量 |
---|---|---|---|
getDeclaredField() |
no | no | yes |
getField() |
no | yes | no |
getDeclaredFields() |
yes | no | yes |
getFields() |
yes | yes | no |
Class對(duì)象提供了四種方法來(lái)獲取類的成員變量,其中getDeclaredField()
和getField()
都是需要通過(guò)提供變量名稱來(lái)獲取單一成員變量渣叛。getFields()
和getDeclaredFields()
則可以通過(guò)鏈返回多個(gè)成員變量丈秩。
Class c = ... // 獲取Class對(duì)象
Field field = c.getField("fieldName") // 通過(guò)成員變量名稱獲取
Field[] fields = c.getFields() // 獲取公有成員變量,包括父類的公有成員變量
通過(guò)以上表淳衙,我們可以得知無(wú)法通過(guò)這四種方法來(lái)獲取父類的私有成員變量蘑秽。
2. 獲取成員變量的名字、類型和修飾器
(1). 名字
通過(guò)Field
類的Field.getName()
來(lái)獲取變量名
Field field = ... // 獲取成員變量對(duì)象
String fieldName = field.getName();
(2). 類型
通過(guò)Field
類的Field.getType()
來(lái)獲取變量類型
Class c = String.class; // String 類
Field[] fields = c.getFields(); // 獲取String類的成員變量
Object fieldType = fields[0].getType(); // 獲取變量類型
(3). 修飾器
通過(guò)Field
類的Field.getModifiers()
來(lái)獲取變量類型
Class c = String.class; // String 類
Field[] fields = c.getFields(); // 獲取String類的成員變量
int modifier = fields[0].getModifiers(); // 所有修飾器都對(duì)應(yīng)到了一個(gè)整型數(shù)值
Modifier.toString(modifier); // 將整型數(shù)值轉(zhuǎn)成相應(yīng)的修飾器字符串
Field
類還提供了Field.isSynthetic()
和Field.isEnumConstant()
方法箫攀。前者確定變量是否是合成的肠牲,后者確定變量是否屬于枚舉常量。
3. 獲取成員變量值靴跛、對(duì)成員變量賦值
Class c = MyObject.class;
Field field = c.getField("fieldName");
MyObject newInstance = new MyObject(); // 創(chuàng)建對(duì)象實(shí)例
Object value = field.get(newInstance); // 從對(duì)象實(shí)例中獲取成員變量的值
field.set(newInstance, value); // 對(duì)成員變量進(jìn)行賦值
三缀雳、方法(method)
先看對(duì)Class
API中獲取method
途徑的總結(jié)。
Class API | 通過(guò)List返回多個(gè)方法 | 返回父類方法 | 返回私有方法 |
---|---|---|---|
getDeclaredMethod() |
no | no | yes |
getMethod() |
no | yes | no |
getDeclaredMethods() |
yes | no | yes |
getMethods() |
yes | yes | no |
獲取方法(method)同樣有四種途徑梢睛,具體差別和獲取成員變量一樣肥印,不再贅述。
需注意的是:使用
getMethod()
和getDeclaredMethod()
時(shí)需要給出參數(shù)的類型绝葡,不帶參數(shù)時(shí)則要給出null
深碱。比較神奇的是:當(dāng)參數(shù)時(shí)原始值(primitive)類型時(shí),你可以直接用int.class
藏畅,boolean.class
等作為參數(shù)類型敷硅。
Class c = String.class;
Method method1 = c.getMethod("charAt", int.class); // 通過(guò)方法名和參數(shù)類型int獲取方法
Method method1 = c.getMethod("getBytes", new Class[]{String.class}); // 通過(guò)方法名和參數(shù)類型String獲取方法
String methodName = method1.getName(); // 獲取方法名
1. 獲取類方法的參數(shù)類型和返回類型(Return Type)
Method method = ... // 獲取方法
Class[] parameterTypes = method.getParameterTypes(); //獲取參數(shù)類型
Class returnType = method.getReturnType(); // 獲取返回類型
2. 獲取類方法的修飾器
Method method = ...
int modifier = method.getModifiers();
3. 檢查參數(shù)數(shù)量是否確定
Method method = ...
boolean varArgs = method.isVarArgs();
4. 調(diào)用方法(method)
通過(guò)Method
的invoke()
調(diào)用方法
Method method = String.class.getMethod("charAt", int.class);
Char returnValue = method.invoke("Hello", 4);
參考文獻(xiàn)
Java Reflection - Tutorials
Java Reflection - Fields
Java Reflection - Methods