Java Reflection API提供對JVM中的類,介面和對象的深入洞察.開發者通常使用API來完成以下的任務,這解釋了為什麼總是使用開發工具,例如debugger和Integrated Development Environments (IDEs):
· 決定一個對象的類.
· 獲得關於一個類的modifiers, fields, methods, constructors, etc的信息.
· 獲得關於一個介面的常量和方法聲明.
· 創建一個類的instance,這個類的名字直到運行時才知道,而且在設計時間時可用或是作為一個運行參數被提供.
· 獲得並設置一個對象的field值,即使field的名字直到運行時程序才會知道.
· 調用一個對象上的方法,即使這個方法直到運行時才會知道.
Reflection的具體使用是在JavaBeans中,這裡你可以通過一個構建工具來操作軟體組件.工具使用reflection來獲取Java 組件(類)的屬性,它們是動態載入.
使用Reflection檢索Class Behavior
為了了解你如何使用Reflection來確定一個類行為,考慮以下Employee class的簡單例子:
public class Employee { public String empNum; public String empName; public Employee() { this( "1", "King"); } public Employee(String empNum, String empName) { empNum = empNum; empName = empName; } public String toString() { return "Employee Details: EmpNumber: " empNum ", EmpName: " empNum; } } import java.lang.reflect.Modifier; public class AnalyzeClass { public static void main(String[] args) { Employee employee = new Employee(); Class klass = employee.getClass(); System.out.println( "Class name: " klass.getName()); System.out.println( "Class super class: " klass.getSuperclass()); int mods = klass.getModifiers(); System.out.println( "Class is public: " Modifier.isPublic(mods)); System.out.println( "Class is final: " Modifier.isFinal(mods)); System.out.println( "Class is abstract: " Modifier.isAbstract(mods)); } } |
編譯Modifier classes並執行AnalyzeClass產生如下結果:
Class name: Employee Class super class: class java.lang.Object Class is public: true Class is final: false Class is abstract: false |
import java.lang.reflect.*; public class DumpMethods { public static void main(String args[]) { try { Class c = Class.forName(args[0]); Method m[] = c.getDeclaredMethods(); for (int i = 0; i < m.length; i ) System.out.println(m[i].toString()); } catch (Throwable e) { System.err.println(e); } } } |
java DumpMethods java.util.Stack
…你得到以下的結果:
public synchronized java.lang.Object java.util.Stack.pop() public java.lang.Object java.util.Stack.push(java.lang.Object) public boolean java.util.Stack.empty() public synchronized java.lang.Object java.util.Stack.peek() public synchronized int java.util.Stack.search(java.lang.Object) |
使用Reflection檢索Attributes
一個類有其他的一些實體,除了迄今為止你看到的那些.變數怎麼樣,舉個例子?你可以使用reflection來獲取這些實體的具體輸出.這裡是使用一個Field class的另一個例子:
import java.lang.reflect.*; public class DumpFields { public static void main(String args[]) { try { Class c = Class.forName(args[0]); Field[] fields = c.getFields(); for (int i = 0; i < fields.length; i ) System.out.println(fields[i].toString()); } catch (Throwable e) { System.err.println(e); } } } |
java DumpFields Employee
你得到以下的結果:
public java.lang.String Employee.empNum public java.lang.String Employee.empName |
使用Reflection檢索Constructors
這個Constructor類的例子將幫助完成對各種constructors運用的理解,以及如何使用它們.
import java.lang.reflect.*; public class DumpConstructors { public static void main(String args[]) { try { Class c = Class.forName(args[0]); Constructor[] constructor = c.getConstructors(); for (int i = 0; i < constructor.length; i ) { System.out.println(constructor[i].toString()); //To print the parameter types Class pvec[] = constructor[i].getParameterTypes(); for (int j = 0; j < pvec.length; j ) System.out.println("param #" j " " pvec[j]); } } catch (Throwable e) { System.err.println(e); } } } |
當你編譯這個代碼的時候並用Employee的一個argument執行它…
javac DumpConstructors Employee
…你得到以下的結果:
public Employee(java.lang.String,java.lang.String) param #0 class java.lang.String param #1 class java.lang.String public Employee() |
使用Reflection在運行時執行Class Methods
假設你有一個類並想要在運行的時候使用它.下列代碼顯示你如何載入這個類並在運行時執行一個所期望的方法.這裡假設的是那個方法的名字是setProperties而且採用java.util.Properties類型的一個argument.
Class newClass = null; Method getInstanceMethod = null; Properties prop = new Properties(); prop.put("argName", "argValue"); try { Object obj = newClass.newInstance(); getInstanceMethod = newClass.getMethod("setProperties", new Class[]{new Properties().getClass()}); } catch (Exception ex) { //Exception in loading Class:" ex.getMessage(); } |
[火星人 ] 程序深入洞察——Java Reflection已經有638次圍觀