posts - 262,  comments - 221,  trackbacks - 0
【1】Method类简介
Java反射技术的一个基本应用之一就是在运行时期间动态地调用方法。要动态地调用方法,首先要获得方法本身。步骤如下:
  1.获得Class对象
  2.调用Class对象的getMethod(String, Class[])方法获得指定的方法
 
getMethod方法的第一个参数用来指定方法的名称,第二个参数是一个Class数组,用来存放代表各个参数类型的Class对象。这个方法有一个值得注意的地方:
 
如果参数类型是原子类型(int,long,short等),要使用诸如int.class,long.class来获取其对应Class对象,而不能使用对应的封装类对象。
 
在获得Method对象之后,就可以在运行时动态地调用方法了。Method类里面最主要的方法有以下几种
  1.获取方法所在的类:                     getDeclaringClass()
  2.获取方法签名中所有声明的抛出异常:getExceptionTypes()
  3.获取方法签名中所有参数的类型:     getParameterTypes()
  4.获取方法签名中返回值的类型:        getReturnType()
  5.调用方法:                               Object invoke(Object obj, Object... args)
 
Method类的核心就是invoke方法,该方法用于Method对象唤起对象中对应的方法,特别要注意的是第二个参数:通常这是一个Object数组,这意味着如果参数是原子类型数据,必须先把他转换成对应的封装类对象,invoke方法会在后台自动将其解压成原子类型。
 
从JDK1.5开始之后,增加了"自动装箱"和"自动开箱"的功能,所以你可以看到在行61处,使用了原子类型数据而非封装类来传递参数。如果是在JDK1.4或以下版本,则此处会报错。建议不采用此种做法,以免出现数据类型完全的问题。


【2】使用反射拷贝对象的思路
 1. 获取源对象的所有成员变量列表

 2. 每次取出变量列表中的一个变量,获取其getXxx()和setXxx(Type)方法名称

 3. 根据getXxx()和setXxx(Type)方法名称获得对应的Method对象

 4. 源对象通过invoke(Object, Class[])方法调用getXxx()方法,获得成员变量的值

 5. 目标对象通过invoke(Object, Class[])的方法的setXxx(Type)方法,为目标对象的成员变量赋值
  
其中关键的代码段格式如下:

 1. 创建Method对象:Class.getMethod(method name, method prameters class array)

 2. 调用方法:method.invoke(object, method parameters class array)


【3】示例代码
        // 获得对象的所有属性
        Field fields[] = classType.getDeclaredFields();

        
for (int i = 0; i < fields.length; i++) {
            Field field 
= fields[i];

            String fieldName 
= field.getName();
            String firstLetter 
= fieldName.substring(01).toUpperCase();

            
// 获得和属性对应的getXXX()方法的名字
            String getMethodName = "get" + firstLetter + fieldName.substring(1);
            
// 获得和属性对应的setXXX()方法的名字
            String setMethodName = "set" + firstLetter + fieldName.substring(1);

            
// 获得和属性对应的getXXX()方法
            Method getMethod = classType.getMethod(getMethodName,
                    new Class[] {});
            
// 获得和属性对应的setXXX()方法,使用filed对象的类型
            Method setMethod = classType.getMethod(setMethodName,
                    
new Class[] { field.getType() });

            
// 调用原对象的getXXX()方法:指定调用的对象和方法的参数值列表
            Object value = getMethod.invoke(object, new Object[] {});
            System.out.println(fieldName 
+ ":" + value);
            
// 调用拷贝对象的setXXX()方法:指定调用的对象和参数值列表(注意必须是Object类型)
            setMethod.invoke(objectCopy, new Object[] { value });
        }


-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要尽力打好一手烂牌。
posted on 2008-09-03 16:05 Paul Lin 阅读(1676) 评论(0)  编辑  收藏 所属分类: J2SE

只有注册用户登录后才能发表评论。


网站导航:
 
<2008年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(19)

随笔分类

随笔档案

BlogJava热点博客

好友博客

搜索

  •  

最新评论

阅读排行榜

评论排行榜