到目前为止,都是通过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岁