採用Class類和java.lang.reflect 類庫一塊兒實現 <反射>機制java
在程序運行期間,Java運行時系統始終爲全部的對象維護一個被稱爲運行時的類型表示。這個信息跟蹤着每一個對象所屬的類。虛擬機利用運行時類型信息選擇相應的方法執行。segmentfault
然而,能夠經過專門的Java類訪問這些信息。保存這些信息的類被成爲Class,這個名字很容易讓人混淆。Object 類中的getClass() 方法將返回一個Class類型的實例。數組
獲取Class對象的三種方法dom
Random generator = new Random();
Class cl = generator.getClass();
System.out.println(cl.getName());//java.util.Random
複製代碼
若是類名保存字符串中,並可在運行時該變,便可使用這種方法。forName() 方法會爆ClassNotFoundException 異常,因此須要進行異常處理。函數
Class.forName() 內部經過反射API根據目標類名將類手動加載到內存中,稱爲類加載器加載方法。加載過程當中會把目標類的static方法,變量,代碼塊加載到JVM,注意此時還沒有建立對象實例測試
String className = "java.util.Random";
Class cl = class.forName(className);
複製代碼
Class cl = Random.class;
複製代碼
Constructor[] getConstructors()
:得到全部public構造器;Constructor[] getDeclaredConstructors()
:得到全部訪問權限的構造器Constructor getConstructor(Class[] params)
:根據指定參數得到對應構造器;Constructor getDeclaredConstructor(Class[] params)
:根據指定參數得到對應構造器;Method[] getMethods()
:得到全部public方法;Method[] getDeclaredMethods()
:得到全部訪問權限的方法;Method getMethod(String name, Class[] params)
:根據方法簽名獲取類自身對應public方法,或者從基類繼承和接口實現的對應public方法;Method getDeclaredMethod(String name, Class[] params)
:根據方法簽名得到對應的類自身聲明方法,訪問權限不限;Field[] getFields()
:得到類中全部public變量Field[] getDeclaredFields()
:得到類中全部訪問權限變量Field getField(String name)
:根據變量名獲得對應的public變量Field getDeclaredField(String name)
:根據變量名得到對應的變量,訪問權限不限;咱們來個例子加深一下印象。spa
public static void printConstructors(Class cl) {
//返回包含Constructor 對象的數組,其中包含了Class對象的全部構造器
Constructor[] constructors = cl.getDeclaredConstructors();
for (Constructor c: constructors) {
//String getName()
//返回一個用於描述構造器、方法或域名的字符串
String name = c.getName();
System.out.print(" ");
String modifiers = Modifier.toString(c.getModifiers());
if (modifiers.length()>0)
System.out.print(modifiers+ " ");
System.out.print(name+"(");
//Class[] getParameterTypes() (在Constructor 和 Method 類中)
//返回一個用於描述參數類型的Class對象數組
printParameterType(c.getParameterTypes());
System.out.println(");");
}
}
複製代碼
public static void printMethods(Class cl) {
//返回包含Method 對象的數組,返回這個類或接口的所有方法,但不包括由超類繼承了的方法
Method[] methods = cl.getDeclaredMethods();
for (Method m:methods) {
//Class getReturnType() (在 Method 類中)
//返回一個用於描述返回類型的Class對象
Class retType = m.getReturnType();
String name = m.getName();
System.out.print(" ");
//打印修飾符、返回類型和方法名稱
String modifiers =Modifier.toString(m.getModifiers());
if (modifiers.length()>0)
System.out.print(modifiers+" ");
System.out.print(retType.getName()+" "+ name + "(");
printParameterType(m.getParameterTypes());
System.out.println(");");
}
}
複製代碼
public static void printFields(Class cl) {
//Field[] getDeclaredFields()
//返回包含Field 對象的數組,這些對象記錄了這個類的所有域
Field[] fields = cl.getDeclaredFields();
for (Field f : fields){
Class type = f.getType();
String name = f.getName();
System.out.print(" ");
String modifiers = Modifier.toString(f.getModifiers());
if (modifiers.length()>0)
System.out.print(modifiers+" ");
System.out.println(type.getName()+" "+ name+ ";");
}
}
複製代碼
public static void printParameterType(Class[] paramTypes) {
for (int j = 0;j<paramTypes.length;j++) {
if (j>0)
System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
}
複製代碼
public static void main(String[] args) {
String name;
if (args.length>0)
name = args[0];
else {
Scanner in = new Scanner(System.in);
System.out.println("Enter class name(e.g java.util.Date): ");
name = in.next();
}
try {
//print class name and superclass name (if != object)
//調用Class 的靜態方法 forName 得到類名對應的Class 對象
Class cl = Class.forName(name);
//獲取父類所對應的Class 對象
Class supercl = cl.getSuperclass();
//返回對應modifiers 中位設置的修飾符的字符串表示
String modifiers = Modifier.toString(cl.getModifiers());
if (modifiers.length()>0)
System.out.print(modifiers+" ");
System.out.print("class "+ name);
//判斷是否有繼承父類
if (supercl != null && supercl != Object.class)
System.out.print(" extends "+ supercl.getName());
System.out.print("\n{\n");
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println("}");
}catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
System.exit(0);
}
複製代碼
反射筆記對象