当前位置: 首页 > 面试题库 >

使用Java动态创建类

阮昊阳
2023-03-14
问题内容

我试图找到有关此信息,但空手而归:

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

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

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

这可能吗,我该怎么做?

编辑:这就是我将使用此方法:

/** 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),但是您不应该那样做。为什么?

  • 使用库的代码应该期望类型Object并使用反射来获取所有字段-这不是一个好主意
  • Java是静态类型的语言,您想引入动态类型-这不是地方。

如果您只是想以未定义的格式来存储数据,则可以将其返回到数组中,例如Object[],或者Map<String, Object>如果要对其进行命名,然后从那里获取它-这样做的唯一目的就是为不必要的类生成省去了很多麻烦包含一些将通过反射获得的数据。

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

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

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

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



 类似资料:
  • 因为类也是对象,所以我们可以在程序运行的时候创建类。 Python 是动态语言。 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。 在之前,我们先了了解下 type() 函数。 首先我们新建一个 hello.py 的模块,然后定义一个 Hello 的 class , class Hello(object): def hello(self, name

  • 我试图使用wro4j创建这个基础结构,用户可以通过它来决定绑定哪些js文件,只需编辑模板,而不需要接触任何Java代码。因此,像http://.../bundle/scrip1.js/scrip2.js/script3.js/script4.js这样的请求将返回一个按要求顺序包含所有四个脚本的包。 但是,必须事先以xml或自定义WroModelFactory实现指定具有资源的组,这仍然不能提供足够

  • 我有多个动态json模板如下 JSON 1 JSON 2 JSON 3 我想在运行时将它们隐藏到JAVA对象中,即在编译时不创建POJO。这可能吗?如果是,如何做到这一点? 我尝试使用Jackson lib将json转换为对象(对象类),但如何创建通用POJO,或者如何使用setter-getter动态创建POJO?

  • 表名,excel文件路径,excel文件名是动态的(它是基于用户输入的)。我是SSIS的新手,我只使用过静态值。如何在SSIS中实现上述场景?

  • 问题内容: 给定一个类名,我想动态创建一个Groovy类,向其添加属性和方法。我使用创建新类 对于我使用的方法 其中it.key是字符串(方法名),it.value是闭包。这很方便,因为我可以指定方法参数类型并进行类型检查。但是,如果不给它赋值,就无法指定动态创建的属性类型。我可以通过显式定义属性的getter和setter来解决此问题。这可行,但是metaClass.name = value或m

  • 问题内容: 我需要动态创建一个类。为了更详细,我需要动态创建Django类的子类。 通过“动态”,我打算基于用户提供的配置创建一个类。 例如 我想要一个命名为该类的子类的类。 该类应具有所选属性的列表。 ....在这种情况下 有什么有用的提示吗?:) 问题答案: 您可以通过调用内置函数并传递适当的参数来动态创建类,例如: 它适用于新型类。我不确定这是否也适用于老式类。