歡迎您光臨本站 註冊首頁

程序深入洞察——Java Reflection

←手機掃碼閱讀     火星人 @ 2014-03-10 , reply:0

  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

  這個基本上是Employee class的一個引用,可以檢索它的所有屬性.還需要更有說服力的嗎?看另外一個關於Method class的例子:

  

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);

  }

  }

  }

  但你編譯這個代碼的時候,用帶有已知類的一個argument來調用它…

  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)

  在上面的結果中列出了所有java.util.Stack class的方法.Method 是在java.lang.reflect中的一個類,負責產生這個結果.

  使用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);

  }

  }

  }

  當你編譯這個代碼的時候並用Employee的一個argument執行它…

  java DumpFields Employee

  你得到以下的結果:

  

public java.lang.String Employee.empNum

  public java.lang.String Employee.empName

  這個結果列出所有屬於該類的fields和ttributes.

  使用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()

  分析結果的時候你會發現Employee類有兩個constructor.第一個是帶參數的constructor(你也可以看到參數類型).第二個沒有採用任何參數,結果是不言而喻的.

  使用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();

  }

  這些工具讓一個IDE開發者很容易適應Java作為一個支持編程的語言.


[火星人 ] 程序深入洞察——Java Reflection已經有638次圍觀

http://coctec.com/docs/java/show-post-61473.html