Java申请动态存储空间 java动态创建类以及方法 |
您所在的位置:网站首页 › php动态生成表格数据保存在数据库中 › Java申请动态存储空间 java动态创建类以及方法 |
如果大家看过我之前的那一篇关于 Java Class类与反射机制 的文章,大家应该对java的动态反射机制有一个初步的了解,这里我们在更进一步,看看java程序能不能自己创建一个java类。 我们在搭建jsp后台的网站时,通常 mysql数据库中的一个表,就对应这我们java后台的一个类,数据库的表中的一行数据,就对应这我们的一个java后台的一个对象。当我们的数据很大的时候,我们可能需要个数据表,这时候如果我们手动在java后台建立相应的类和对象,就会显得非常的繁琐,有没有什么办法,能帮我们把java的类创建出来呢? 答案是有的, 这里我们就来说一下,怎样用java代码创建类: 先来看两段代码:(这两段代码需要一个外部类,cglib-nodep-2.2.2.jar,不同的cglib库可能会有不兼容的情况,导致错误,这里我提供了我正在使用的cglib-nodep-2.2.2.jar,大家可以在这篇博客页面连接中下载。) CglibBean类: package Dynamic_class3; import java.util.Iterator; public class CglibBean { // 实体Object public Object object = null; // 属性map public BeanMap beanMap = null; public CglibBean() { super(); } @SuppressWarnings("unchecked") public CglibBean(Map propertyMap) { this.object = generateBean(propertyMap); this.beanMap = BeanMap.create(this.object); } /** * 给bean属性赋值 * @param property * 属性名 * @param value * 值 */ public void setValue(String property, Object value) { beanMap.put(property, value); } /** * 通过属性名得到属性值 * @param property * 属性名 * @return 值 */ public Object getValue(String property) { return beanMap.get(property); } /** * 得到该实体bean对象 * @return */ public Object getObject() { return this.object; } @SuppressWarnings("unchecked") private Object generateBean(Map propertyMap) { BeanGenerator generator = new BeanGenerator(); Set keySet = propertyMap.keySet(); for (Iterator i = keySet.iterator(); i.hasNext();) { String key = (String) i.next(); generator.addProperty(key, (Class) propertyMap.get(key)); } return generator.create(); } }
CglibTest测试类: package Dynamic_class3; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; //这个类存在的问题就是它生成的类中的参数的顺序是随机的,不能借助传入时的顺序来找到(必须借助参数的名字),(而动态编译的时候,参数的名字又不可能事先得知) //这里生成的类的属性都是私有的,get和set方法都是公有的。注意使用 /** * Cglib测试类 * * @author cuiran * @version 1.0 */ public class CglibTest { // 这里编译类是没有类名的,你需要自己给它取一个名字(比如叫 clazz 啊什么的·····), // 这个函数用来动态的创建类,其中param_type是一个多行,两列的二维数组,第一列是属性名,第二列是属性的类型(Integer,String····),Value是参数的初始值。 public static Class create_class(String[][] param_type) throws ClassNotFoundException { // 设置类成员属性 HashMap propertyMap = new HashMap(); for (int i = 0; i < param_type.length; i++) { propertyMap.put(param_type[i][0], Class.forName("java.lang." + param_type[i][1])); } // 生成动态 Bean CglibBean bean = new CglibBean(propertyMap); // 给 Bean 设置值 for (int i = 0; i < param_type.length; i++) { switch (param_type[i][1]) { case "Integer": bean.setValue(param_type[i][0], new Integer(0)); break; case "String": bean.setValue(param_type[i][0], new String("xx")); break; case "Float": bean.setValue(param_type[i][0], new Float(0)); break; case "Double": bean.setValue(param_type[i][0], new Double(0)); break; default: break; } } // 从 Bean 中获取值,当然了获得值的类型是 Object for (int i = 0; i < param_type.length; i++) { System.out.println(" >> " + param_type[i][0] + " = " + bean.getValue(param_type[i][0])); } // 获得bean的实体 Object object = bean.getObject(); // 通过反射查看所有方法名 Class clazz = object.getClass(); // Method[] methods = clazz.getDeclaredMethods(); // for (int i = 0; i < methods.length; i++) { // System.out.println(methods[i].getName()); // } return clazz; } // 这个函数用来动态的创建类并且获取对象,其中param_type是一个多行,两列的二维数组,第一列是属性名,第二列是属性的类型(Integer,String····),Value是参数的初始值。 public static Object create_class_and_object(String[][] param_type, String[] Value) throws ClassNotFoundException { // 设置类成员属性 HashMap propertyMap = new HashMap(); for (int i = 0; i < param_type.length; i++) { propertyMap.put(param_type[i][0], Class.forName("java.lang." + param_type[i][1])); } // 生成动态 Bean CglibBean bean = new CglibBean(propertyMap); // 给 Bean 设置值 for (int i = 0; i < param_type.length; i++) { switch (param_type[i][1]) { case "Integer": bean.setValue(param_type[i][0], new Integer(Integer.parseInt(Value[i]))); break; case "String": bean.setValue(param_type[i][0], new String(Value[i])); break; case "Float": bean.setValue(param_type[i][0], new Float(Value[i])); break; case "Double": bean.setValue(param_type[i][0], new Double(Value[i])); break; default: break; } } // 获得bean的实体 Object object = bean.getObject(); // 通过反射查看所有方法名 // Class clazz = object.getClass(); // Method[] methods = clazz.getDeclaredMethods(); // for (int i = 0; i < methods.length; i++) { // System.out.println(methods[i].getName()); // } return object; } // 其中这个参数用来返回一个对象,对象的属性形式是“类型为:class // java.lang.Integer,参数名为:$cglib_prop_id,参数值为:1”,参数顺序仍然是乱的。 public Object create_object(class_info clin, String[] str) throws InstantiationException, IllegalAccessException { // 创建相应的对象 Object obj = clin.clazz.newInstance(); // 通过反射API操作属性 Field[] f = clin.clazz.getDeclaredFields(); for (int j = 0; j < f.length; j++) { f[j].setAccessible(true);// 这个属性不需要安全检查了,可以直接访问 // System.out.println(f[i].getType().toString()); String param_name = f[j].getName(); // 在类的属性表中查找这个属性,找到相应的类型 for (int k = 0; k < f.length; k++) { if (("$cglib_prop_" + clin.param_type[k][0]).equals(param_name)) {// 说明参数名匹配成功 // 从参数表中取出参数类型 switch (clin.param_type[k][1]) { // 这里数据库中的数据的顺序和class_info中的属性表的顺序是相同的,所以可以直接用参数表的下标号来作为str的下标号 case "String": f[j].set(obj, str[k]);// 通过反射直接写属性 break; case "Integer": f[j].set(obj, Integer.parseInt(str[k]));// 通过反射直接写属性 break; default: System.err.println("这个类中含有暂时没有考虑到的参数-----"); break; } break; } else if (k == f.length - 1) { System.out .println("参数表名为:$cglib_prop_" + clin.param_type[k][0] + ",而类中的属性名为:" + param_name); System.err.println("发生错误,找不到参数名。"); } } // System.out.println(obj.getUname());//通过反射直接读属性的值 // System.out.println("新加入的参数类型为:" + f[j].getType().toString() // + ",参数名为:" + f[j].getName() + ",值为:" + f[j].get(obj)); } return obj; } static public int find_field(Class clazz, String para_name) { Field[] f = clazz.getDeclaredFields(); for (int i = 0; i < f.length; i++) { f[i].setAccessible(true);// 这个属性不需要安全检查了,可以直接访问 if (("$cglib_prop_" + para_name).equals(f[i].getName())) { return i; } } return -1; } /** * 获取属性类型(type),属性名(name),属性值(value)的map组成的list 这个函数暂时没办法用,(因为存在问题,无法改正) * */ // 这个函数没有问题了 static public List getFiledsInfo(Object o) { Field[] fields = o.getClass().getDeclaredFields(); String[] fieldNames = new String[fields.length]; List list = new ArrayList(); Map infoMap = null; for (int i = 0; i < fields.length; i++) { infoMap = new HashMap(); infoMap.put("type", fields[i].getType().toString()); infoMap.put("name", fields[i].getName()); infoMap.put("value", getFieldValueByName(fields[i].getName(), o)); list.add(infoMap); } return list; } /** * 根据属性名获取属性值 * */ static public Object getFieldValueByName(String fieldName, Object o) { try { // 对属性名做预处理,截去类名的前十二个 无用的字符 // fieldName = fieldName.substring(12); // 借助类中的get方法来获取对象的属性的值。 String firstLetter = fieldName.substring(0, 1).toUpperCase(); String getter = "get" + firstLetter + fieldName.substring(1); //System.out.println("show method name" + getter); Method method = o.getClass().getMethod(getter, new Class[] {}); // System.out.println(Modifier.toString(method.getModifiers())); Object value = method.invoke(o, new Object[] {}); return value; } catch (Exception e) { e.printStackTrace(); } return o; } static public Object getFieldValueByName2(String fieldName, Object o, class_info clin) { Class clazz = o.getClass(); Field[] f = clazz.getDeclaredFields(); for (int i = 0; i < f.length; i++) { String param_name = f[i].getName(); String pa_name = param_name.substring(12); if (fieldName.equals(pa_name)) { try { return f[i].get(o); } catch (IllegalArgumentException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (IllegalAccessException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } return null; } @SuppressWarnings("unchecked") public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //这里定义类中的属性名,和属性的类型, String[][] param = { { "param1", "String" }, { "param2", "Integer" } }; //这里定义创建对象时属性的值, String[] v = { "1111", "2222" }; //创建一个类 Class c = create_class(param); Object ob = create_class_and_object(param, v); System.out.println(getFieldValueByName("param1", ob)); // List t = getFiledsInfo((Object) ob); // System.out.println(((HashMap ) t.get(0)).get("name")); // test te = new test(); // List t = getFiledsInfo((Object)te); // System.out.println(((HashMap ) // t.get(0)).get("value")); } }
这两段代码中比较关键的部分我都做了注释,大家可以自行阅览,其中被注释掉的代码,是用来展示创建类过程中的其他功能的,有兴趣钻研的朋友也可以试着运行一下,有什么看不懂的地方,欢迎留言
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |