java反射—— 對類的分析
轉自http://uuhorse.iteye.com/blog/1706466
反射API使得Java語言更易實現執行時的動態性,獲取Java程式在執行時刻的內部結構,如Java列中的構造方法、域和方法等。反射API的主要功能包括:
① 確定一個物件的類② 取出類的修飾符(modifiers),欄位,方法,構造器和超類
③ 找出某個介面裡定義的常量和方法說明
④ 建立一個類例項,這個例項在執行時刻才有名字(執行時間才生成的物件)
⑤ 取得和設定物件資料成員的值,如果資料成員名是執行時刻確定的也能做倒。
⑥ 在執行時刻呼叫動態物件的方法
⑦ 建立陣列,陣列大小和型別在執行時刻才確定。也能更改陣列成員的值。
① 獲取物件的類(Class物件)
Class c = obj.getClass();
② 獲取一個類的超類
Class sc = c.getSuperclass();
③ 獲取類的名字
Class c = obj.getClass();
String name = c.getName();
④ 獲取類的修飾符
Class c = obj.getClass();
int m = c.getModifiers();
此處getModifiers()方法返回的是個整型的結果,結果m並不具體表示哪一種修飾符。先看java.lang.reflect.Modifier類,該類對修飾符進行了相應的包裝。
類Modifier中定義了一系列的類描述符常量:Modifier.ABSTRACT、Modifier.FINAL、Modifier.PUBLIC等。getModifiers()方法返回的即是類的所有修飾符分別對應的整型值的或運算結果。
如public abstract class MyClass{},new MyClass().getClass().getModfiers()即得到Modifier.ABSTRACT | Modifier.PUBLIC。
同時Modifier類提供了一些列的方法,用於判斷getModifiers()返回的整型數字中包含的類修飾符:Modifier.isPublic(m)、Modifier.isAbstract(m)、Modifier.isFinal(m)等。
public class Point {
private int x;
private int y;
private String s1 ="ball";
private String s2="hubin";
private String s3="zhangxiaoxiang";
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
// 分析類的修飾符
public static void printModifiers(Object obj) {
System.out.print("Modifier: \n");
Class c = obj.getClass();
int m = c.getModifiers();
if (Modifier.isPublic(m))
System.out.print("public \n");
if (Modifier.isAbstract(m))
System.out.print("abstract \n");
if (Modifier.isFinal(m))
System.out.print("final \n");
System.out.println(c.getName());
}
public static void main(String[] args) throws Exception {
Point pt1 = new Point(3, 5);
printModifiers(pt1);
}
輸出結果:
Modifier:
public
reflect.Point
⑤ 確定一個類實現的介面
Class[] theInterfaces = c.getInterfaces();
從上面的語句中可以看到,介面在反射的API中也是用Class表示的,介面是一種特殊的抽象類。可以使用Class類的isInterface()方法判斷一個Class型別是一個類還是介面。
// 分析類的介面
public static void printInterfaceNames(Object o) {
Class c = o.getClass();
Class[] theInterfaces = c.getInterfaces();
for (int i = 0; i < theInterfaces.length; i++) {
String interfaceName = theInterfaces[i].getName();
System.out.println(interfaceName);
}
}
// 判斷介面
public static void verifyInterface(Class c) {
String name = c.getName();
if (c.isInterface()) {
System.out.println(name + " 是介面.");
} else {
System.out.println(name + " 是類.");
}
}
⑥ 獲取類的欄位
一個類的欄位(Field)可能來自本類、父類、實現的介面或者介面的介面,可以使用Class物件的getFields()方法獲取類中所有的public屬性的欄位的陣列(Field物件陣列)。Field物件提供方法取得欄位的名字、型別和描述符,甚至可以給欄位賦值或者取欄位的值。當然,Class類物件提供了getDeclaredFields()方法獲取包括public屬性在內的所有在類中宣告瞭的域。
// 分析類的欄位
public static void printFieldNames(Object o) {
Class c = o.getClass();
//public的欄位
Field[] publicFields = c.getFields();
for (int i = 0; i < publicFields.length; i++) {
String fieldName = publicFields[i].getName();
Class typeClass = publicFields[i].getType();
String fieldType = typeClass.getName();
System.out.println("欄位名: " + fieldName + ", 型別: " + fieldType);
}
//所有的欄位
Field[] allFields = c.getDeclaredFields();
for (int i = 0; i < allFields.length; i++) {
String fieldName = allFields[i].getName();
Class typeClass = allFields[i].getType();
String fieldType = typeClass.getName();
System.out.println("欄位名: " + fieldName + ", 型別: " + fieldType);
}
}
⑦ 獲取構造方法
構造方法是在建立類物件時呼叫的特殊方法,構造方法可以過載,由它們的引數加以區別。呼叫getConstructors方法可以取得類構造方法的有關資訊,這個方法返回一個陣列的
Constructor物件。可以用 Constructor物件裡的相關方法來確定構造方法的名字、描述符、引數型別和丟擲的意外列表。也可以用Constructor.newInstance建立一個新的Constructor物件。
//分析類的構造方法
public static void showConstructors(Object o) {
Class c = o.getClass();
Constructor[] theConstructors = c.getConstructors();
for (int i = 0; i < theConstructors.length; i++) {
System.out.print(theConstructors[i].getName());
System.out.print(" ( ");
Class[] parameterTypes = theConstructors[i].getParameterTypes();
for (int k = 0; k < parameterTypes.length; k++) {
String parameterString = parameterTypes[k].getName();
System.out.print(parameterString + " ");
}
System.out.println(")");
}
}
⑧ 獲取成員方法
如何找出類的public方法呢?當然是呼叫getMethods方法。由getMethods方法返回一個陣列,陣列元素型別是Method物件。方法的名字,型別,引數,描述和丟擲的意外都可
以由Method物件的方法來取得。用 Method.invoke 方法自己呼叫這個方法。
Method類的物件可以通過getName取方法名、getReturnType取返回值的型別、用
getParameterTypes取得引數型別(Class物件)的陣列,對每個引數用getName取引數的型別名。
同樣,對於非public的方法,可以使用getDeclaredMethods()方法獲取。
//分析類中的成員方法
public static void showMethods(Object o) {
Class c = o.getClass();
Method[] theMethods = c.getMethods();
for (int i = 0; i < theMethods.length; i++) {
String methodString = theMethods[i].getName();
System.out.println("Name: " + methodString);
String returnString = theMethods[i].getReturnType().getName();
System.out.println(" Return Type: " + returnString);
Class[] parameterTypes = theMethods[i].getParameterTypes();
System.out.print(" Parameter Types:");
for (int k = 0; k < parameterTypes.length; k++) {
String parameterString = parameterTypes[k].getName();
System.out.print(" " + parameterString);
}
System.out.println();
}
}
相關文章
- 對比分析Java反射獲取例項的速度Java反射
- Java中的類反射機制Java反射
- java反射之Class類Java反射
- Java jvm 類載入 反射JavaJVM反射
- java反射呼叫set和get方法的通用類Java反射
- Java列舉類、註解和反射Java反射
- Java的反射Java反射
- java高效能反射及效能對比Java反射
- Java基礎對反射知識總結Java反射
- Java 方法的反射Java反射
- Java日期類分析Java
- Java知識點總結(反射-獲取類的資訊)Java反射
- 【Java 反射學習】Java 反射基礎Java反射
- [Java 反射學習] Java 反射基礎Java反射
- 揭秘Java反射:如何輕鬆獲取類的屬性及父類屬性Java反射
- Java 反射Java反射
- Java——反射Java反射
- Java反射Java反射
- Java反射—初探反射基礎Java反射
- Java的反射機制Java反射
- 說說java的反射Java反射
- Java反射與hook混用反射某支付的方法Java反射Hook
- java反射構建物件和方法的反射呼叫Java反射物件
- 類的反射和依賴注入反射依賴注入
- PHP --反射 --獲取類的方法PHP反射
- 03-Java核心類庫_列舉、註解與反射Java反射
- Java核心技術梳理-類載入機制與反射Java反射
- Java 反射修改類的常量值、靜態變數值、屬性值Java反射變數
- Java 反射 APIJava反射API
- Java 反射原理Java反射
- 20201209——java反射Java反射
- 淺析Java反射--JavaJava反射
- 淺談java中的反射Java反射
- Java 中的 反射機制Java反射
- 淺談Java的反射原理Java反射
- Java安全基礎之Java反射機制和ClassLoader類載入機制Java反射
- java透過反射統計實體類和父類中為空的欄位數量Java反射
- 用反射呼叫Method類的invoke方法反射
- 反射獲取注入到spring中的類物件的工具類反射Spring物件