標籤:
什麼時候使用Reflection:
在java語言中,建立一個類的對象通常使用new operator,但是如果預先不知道Class的名字,類名是在程式運行過程中通過參數傳遞過來,就沒法使用這種方法了,這種情況下就只能使用Reflection機制了。
使用 Reflection機制可以大大提高程式的可擴充性和可維護性(動態建立類名),所付出的代價是效率的降低。
Reflection機制最常用於struts機制。怎麼知道它是一個Action和FormBean而不是一個Servlet?這就是在Web Server啟動時,它先從struts-config檔案中得到所有Action、FormBean的路徑、配置資訊,再利用Reflection機制來判斷Action和FormBean是不是一個Action或是一個Servlet。
*** struts是開源軟體。使用Struts的目的是為了協助我們減少在運用MVC設計模型來開發Web應用的時間。
*** MVC架構:
l Jsp----->view(視圖)
l Servlet------>Cotroller(控制)
l JavaBean------->Model(模型)
使用步驟:
1。獲得Class的object。有三種方法:
1.Class aClassObj = a.getClass();
2.Class aClassObj = a.class();
3.Class aClassObj = Class.forName( "a" );
2。由於new操作會調用到constructor,所以第二步是獲得constructor的object。有以下兩個方法:
1.Constructor cons = aClassObj.getConstructor(Class[] );
2.Constructor[] cons = aClassObj.getConstructors();
其中1中的Class[]中的每一個成員都是用來描述constructor中的參數類型的Classobject。如:假如在類a中有形如constructor(String str , OutputStream out )的constructor,那麼得到它的Constructorobject的方法就是
Class[] paraType = new Class [ 2 ];
paraType[ 0 ] = String.class;
paraType[ 1 ] = OutputStream.class;
Constructor cons = aClassObj.getConstructor ( paraType );
假如想利用無參constructor來獲得一個Constructor的object,就要使用Constructorcons = aClassObj.newInstance()方法。
3。獲得該類執行個體
publicObject aObject()
{
Object[] paraObjArr = new Object[2];
Object[ 0 ] = "name";
Object[ 1 ] = new OutputStream ( "text.txt" );
return cons.newInstance ( paraObjArr )
}
4。獲得該類中的方法。有以下兩種方式:
1. 使用MethodallMethod []= aClassObj.getDeclaredMethods()可以得到所有該類中的方法的對象
2.使用getMethod(參數)可以獲得某個具體的方法,其中參數同擷取建構函式時類似,需要paraType。假如有一個名為"setName"具有一個String類型的參數的方法,可以這樣使用:
Class[] methodParaType = new Class[ 1 ];
methodParaType [0] = String.class;
Method gotmethod = aClassObj.getMethod( "setName" ,methodParaType);
5。使用該類中的方法。接著上例:
Object[]methodPara = new Object[1];
methodPara[0] = "wang";
gotmethod.invoke( cons.newInstance ( paraObjArr),methodPara);
例:
import java.ang.reflect.*;
public classDumpMethods{
publicstatic 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.utilStack
它的結果為:
public java.lang.Objectjava.util.Stack.push(java.lang.Object)
public synchronized java.lang.Objectava.util.Stack.pop()
public synchronized java.lang.Objectjava.util.Stack.peek()
public booleanjava.util.Stack.empty()
public synchronized intjava.util.Stack.search(java.lang.Object)
分析:
這個程式使用Class.forName載入指定的類,然後調用getDeclaredMethods來擷取這個類中定義了的方法列表。另外getDeclaredField()可以獲得類的欄位域、getDeclaredConstructors()可以獲得類的建構函式。
Java的Reflection機制