Reflection的三個動態性質

轉自http://www.blogjava.net/ronghao

一、執行期根據方法的名稱來執行方法

下面的示例演示了這一操作:
import java.lang.reflect.*;
public class method2 {
   
public int add(int a, int b) {
       
return a + b;
   }

   
public static void main(String args[]) {
       
try {
           Class cls 
= Class.forName("method2");
           Class partypes[] 
= new Class[2];
           partypes[
0= Integer.TYPE;
           partypes[
1= Integer.TYPE;
           Method meth 
= cls.getMethod("add", partypes);
           method2 methobj 
= new method2();
           Object arglist[] 
= new Object[2];
           arglist[
0= new Integer(37);
           arglist[
1= new Integer(47);
           Object retobj 
= meth.invoke(methobj, arglist);
           Integer retval 
= (Integer) retobj;
           System.out.println(retval.intvalue());
       }
 catch (Throwable e) {
           System.err.println(e);
       }

   }

}

注:上面劃線的粗體字最好用Object methobj =  cls.newInstance();來代替,原因很明顯如果這個類及方法事先都是清楚的也不需要用reflection了
    假如一個程序在執行的某處的時候才知道需要執行某個方法,這個方法的名稱是在程序的運行過程中指定的 (例如,JavaBean 開發環境中就會做這樣的事),那麼上面的程序演示瞭如何做到。上例中,getMethod 用於查找一個具有兩個整型參數且名爲 add 的方法。找到該方法並創建了相應的 Method 對象之後,在正確的對象實例中執行它。執行該方法的時候,需要提供一個參數列表,這在上例中是分別包裝了整數 37 和 47 的兩個 Integer 對象。執行方法的返回的同樣是一個 Integer 對象,它封裝了返回值 84。

二、執行期創建新的對象

對於構造器,則不能像執行方法那樣進行,因爲執行一個構造器就意味着創建了一個新的對象 (準確的說,創建一個對象的過程包括分配內存和構造對象)。所以,與上例最相似的例子如下:

import java.lang.reflect.*;
public class constructor2 {
   
public constructor2() {
   }

   
public constructor2(int a, int b) {
       System.out.println(
"a = " + a + " b = " + b);
   }

   
public static void main(String args[]) {
       
try {
           Class cls 
= Class.forName("constructor2");
           Class partypes[] 
= new Class[2];
           partypes[
0= Integer.TYPE;
           partypes[
1= Integer.TYPE;
           Constructor ct 
= cls.getConstructor(partypes);
           Object arglist[] 
= new Object[2];
           arglist[
0= new Integer(37);
           arglist[
1= new Integer(47);
           Object retobj 
= ct.newInstance(arglist);
       }
 catch (Throwable e) {
           System.err.println(e);
       }

   }

}

三、改變字段(域)的值

reflection 的還有一個用處就是改變對象數據字段的值。reflection 可以從正在運行的程序中根據名稱找到對象的字段並改變它,下面的例子可以說明這一點:

import java.lang.reflect.*;
public class field2 {
   
public double d;
   
public static void main(String args[]) {
       
try {
           Class cls 
= Class.forName("field2");
           Field fld 
= cls.getField("d");
           field2 f2obj 
= new field2();
           System.out.println(
"d = " + f2obj.d);
           fld.setDouble(f2obj, 
12.34);
           System.out.println(
"d = " + f2obj.d);
       }
 catch (Throwable e) {
           System.err.println(e);
       }

   }

}
這個例子中,字段 d 的值被變爲了 12.34。
實際開發時用Common BeanUtils 
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章