【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( 0 ,  1 ).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 });
        }