到目前为止,都是通过Class类的方法获取对应类的属性、方法和构造方法的详细信息。接下来通过之前的获取方法来动态创建对象、修改属和调用方法。

1.创建对象、修改属性

  • 通过Class类的newInstance()方法创建对象。
**
 * 动态创建对象,动态添加属性
 * 必须先添加属性,再实例化,然后设置属性值
 * @author meng
 *
 */
public class DynamicCreateObject {

    public static Object getDynamicObject(Map<String, String> map) throws Exception{
        //创建一个名称为Template的类
        Object template = addField("Template"+UUID.randomUUID(),map);    
        return template;
    }
    
    public static Object addField(String className,Map<String,String> fieldMap) throws Exception {
        // 获取javassist类池
        ClassPool pool = ClassPool.getDefault();
        // 创建javassist类
        CtClass ctClass = pool.makeClass(className,pool.get(Object.class.getName()));
        // 为创建的类ctClass添加属性
        Iterator<Entry<String, String>> iterator = fieldMap.entrySet().iterator();
        
        // 遍历所有的属性
        while (iterator.hasNext()) {
            Map.Entry<String,String> entry = (Map.Entry<String,String>) iterator.next();
            String fieldName = (String)entry.getKey();
            String fieldValue = (String)entry.getValue();
            // 增加属性,这里仅仅是增加属性字段
            String fieldType = fieldValue.getClass().getName();
            CtField ctField = new CtField(pool.get(fieldType),fieldName, ctClass);
            ctField.setModifiers(Modifier.PUBLIC);
            ctClass.addField(ctField);
        }
        // 为创建的javassist类转换为java类
        Class<?> c = ctClass.toClass();
        // 为创建java对象
        Object newObject = c.newInstance();
        iterator = fieldMap.entrySet().iterator();
        // 遍历所有的属性
        while (iterator.hasNext()) {
            Map.Entry<String,String> entry = (Map.Entry<String,String>) iterator.next();
            String fieldName = (String)entry.getKey();
            String fieldValue = (String)entry.getValue();
            // 为属性赋值
            setFieldValue(newObject,fieldName,fieldValue);
        }
        return newObject;
    }
    
    public Object getFieldValue(Object object, String fieldName) throws Exception {
        Object result = null;
        // 获取对象的属性域
        Field fu = object.getClass().getDeclaredField(fieldName);
        // 设置对象属性域的访问属性
        fu.setAccessible(true);
        // 获取对象属性域的属性值
        result = fu.get(object);
        return result;
    }
    
    private static Object setFieldValue(Object object, String fieldName, String val) throws Exception {
        Object result = null;
        Field fu = object.getClass().getDeclaredField(fieldName); // 获取对象的属性域
        // 设置对象属性域的访问属性
        fu.setAccessible(true);
        // 设置对象属性域的属性值
        fu.set(object,val);
        // 获取对象属性域的属性值
        result = fu.get(object);
        return result;
    }
    
}

可以根据用户运行时输入的信息,动态创建不同的对象,在调用相关的方法执行相关的功能。

通过Class类的newInstance()方法创建对象,该方法要求Class对应类有无参构造方法。执行newInstance()方法实际上就是使用对应类的无参构造方法来创建该类的实例,其代码等价于:

Super sup = new Super();

如果Super类没有无参构造方法,运行时就会抛出一个InstantionException实例化异常。

  • 通过Constructor的newInstance(Object[] args)方法创建对象。

如果想要使用有参构造方法创建对象,则需要先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance(Object[] args)方法来创建该Class对象对应类的实例。

通过Constructor的newInstance()方法。也可以创建无参对象,这样在调用getDeclaredConstructor((Class[] args))和newInstance(Object[] args)方法时,参数列表为空即可。

2.调用方法

package cn.lanqiao01;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {

    public String getName(String name, String address, Integer age) {
        return name + "是一名人民教师,在"+address+","+age+"岁";
    }

    public static void main(String[] args) {
        try {
            Class<?> clazz = Class.forName("cn.lanqiao01.Test");
            Method method = clazz.getMethod("getName", String.class, String.class, Integer.class);
            Object obj = method.invoke(clazz.newInstance(), "李梅","上海", 21);
            System.out.println(obj);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

结果:

李梅是一名人民教师,在上海,21岁