`

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 
 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics