使用Java动态创建类 [英] Creating classes dynamically with Java

查看:77
本文介绍了使用Java动态创建类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到有关这方面的信息,但空手而归:

I have tried to find information about this but have come up empty handed:

我认为可以使用反射或代理在Java中动态创建一个类但是我不知道怎么做。我正在实现一个简单的数据库框架,我使用反射创建SQL查询。该方法获取具有数据库字段作为参数的对象,并基于该创建查询。但是如果我也可以动态创建对象本身就非常有用,所以我不需要为每个表都有一个简单的数据包装器对象。

I gather it is possible to create a class dynamically in Java using reflection or proxies but I can't find out how. I'm implementing a simple database framework where I create the SQL queries using reflection. The method gets the object with the database fields as a parameter and creates the query based on that. But it would be very useful if I could also create the object itself dynamically so I wouldn't have the need to have a simple data wrapper object for each table.

动态类只需要简单的字段( String Integer Double ),例如

The dynamic classes would only need simple fields (String, Integer, Double), e.g.

public class Data {
  public Integer id;
  public String name;
}

这可行,我该怎么做?

编辑:这是我如何使用它:

This is how I would use this:

/** Creates an SQL query for updating a row's values in the database.
 *
 * @param entity Table name.
 * @param toUpdate Fields and values to update. All of the fields will be
 * updated, so each field must have a meaningful value!
 * @param idFields Fields used to identify the row(s).
 * @param ids Id values for id fields. Values must be in the same order as
 * the fields.
 * @return
 */
@Override
public String updateItem(String entity, Object toUpdate, String[] idFields,
        String[] ids) {
    StringBuilder sb = new StringBuilder();

    sb.append("UPDATE ");
    sb.append(entity);
    sb.append("SET ");

    for (Field f: toUpdate.getClass().getDeclaredFields()) {
        String fieldName = f.getName();
        String value = new String();
        sb.append(fieldName);
        sb.append("=");
        sb.append(formatValue(f));
        sb.append(",");
    }

    /* Remove last comma */
    sb.deleteCharAt(sb.toString().length()-1);

    /* Add where clause */
    sb.append(createWhereClause(idFields, ids));

    return sb.toString();
}
 /** Formats a value for an sql query.
 *
 * This function assumes that the field type is equivalent to the field
 * in the database. In practice this means that this field support two
 * types of fields: string (varchar) and numeric.
 *
 * A string type field will be escaped with single parenthesis (') because
 * SQL databases expect that. Numbers are returned as-is.
 *
 * If the field is null, a string containing "NULL" is returned instead.
 * 
 * @param f The field where the value is.
 * @return Formatted value.
 */
String formatValue(Field f) {
    String retval = null;
    String type = f.getClass().getName();
    if (type.equals("String")) {
        try {
            String value = (String)f.get(f);
            if (value != null) {
                retval = "'" + value + "'";
            } else {
                retval = "NULL";
            }
        } catch (Exception e) {
            System.err.println("No such field: " + e.getMessage());
        }
    } else if (type.equals("Integer")) {
        try {
            Integer value = (Integer)f.get(f);
            if (value != null) {
                retval = String.valueOf(value);
            } else {
                retval = "NULL";
            }
        } catch (Exception e) {
            System.err.println("No such field: " + e.getMessage());
        }
    } else {
        try {
            String value = (String) f.get(f);
            if (value != null) {
                retval = value;
            } else {
                retval = "NULL";
            }
        } catch (Exception e) {
            System.err.println("No such field: " + e.getMessage());
        }
    }
    return retval;
}


推荐答案

可以生成课程(通过 cglib asm javassist bcel ),但你不应该这样做。为什么?

It is possible to generate classes (via cglib, asm, javassist, bcel), but you shouldn't do it that way. Why?


  • 使用该库的代码应该是类型 Object 并获得所有使用反射的字段 - 不是一个好主意

  • java是静态类型语言,你想引入动态类型 - 它不是那个地方。

  • the code that's using the library should expect type Object and get all the fields using reflection - not a good idea
  • java is statically typed language, and you want to introduce dynamic typing - it's not the place.

如果您只是希望数据采用未定义的格式,那么您可以在数组中返回它,例如 Object [] ,或者 Map< String,Object> 如果你想要它们命名,并从那里得到它 - 它将为你不必要的类生成节省很多麻烦,仅用于包含一些数据这将通过反射获得。

If you simply want the data in an undefined format, then you can return it in an array, like Object[], or Map<String, Object> if you want them named, and get it from there - it will save you much trouble with unneeded class generation for the only purpose of containing some data that will be obtained by reflection.

你可以做的是拥有预定义的类来保存数据,并将它们作为参数传递给查询方法。例如:

What you can do instead is have predefined classes that will hold the data, and pass them as arguments to querying methods. For example:

 public <T> T executeQuery(Class<T> expectedResultClass, 
      String someArg, Object.. otherArgs) {..}

因此,您可以对传递的 expectedResultClass 使用反射来创建该类型的新对象,并使用查询结果填充它。

Thus you can use reflection on the passed expectedResultClass to create a new object of that type and populate it with the result of the query.

那就是说,我认为你可以使用现有的东西,比如ORM框架(Hibernate,EclipseLink),spring的 JdbcTemplate 等。

That said, I think you could use something existing, like an ORM framework (Hibernate, EclipseLink), spring's JdbcTemplate, etc.

这篇关于使用Java动态创建类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆