0

我需要使用 suns CodeModel 库生成代码和在这种情况下的注释。注释值是一个 Class 对象。但是,该类在编译时是未知的。我现在的解决方案是:

JAnnotationUse oneToMany = field.annotate(OneToMany.class)
    .param("targetEntity", Class.forName(className);

然而,这显然要求相应的类在类路径上。我想避免用户不得不处理这些问题。

当然,另一种选择是生成 java 源代码文件并在之后对其进行操作(作为纯字符串),但这看起来很混乱。

CodeModel 有没有办法使用纯字符串 className + ".class" 代替?

4

2 回答 2

0

您可以通过捕获ClassNotFoundException来处理类不在类路径中的情况:

try {
 JAnnotationUse oneToMany = field.annotate(OneToMany.class)
    .param("targetEntity", Class.forName(className);
} catch (ClassNotFoundException e) {
 // handle the exception
}

您处理异常的部分实际上取决于您要实现的目标,具体取决于您可能想要记录错误/添加另一个注释/抛出异常/...

于 2013-06-27T09:07:51.900 回答
0

行。这是我的解决方案。使用 javaassist 在运行时生成类和相应的 Class 对象。由于最终结果将是

 @OneToMany(targetEntity = com.foo.Bar.class)

作为java源代码文件中的普通文本,这个生成的“虚拟类”实际上并不等同于被引用的真实类。

因此,我们按照 Guillaume 的指示调整注释的创建并捕获ClassNotfoundExeption. 在异常处理程序中,我们调用generateDummyClass使用 javaassist 创建 Class 对象的方法:

JAnnotationUse oneToMany = field.annotate(OneToMany.class);
//...snipped...
    try {
        oneToMany.param("targetEntity", Class.forName(jpaProperty.getTargetEntity()));
    } catch (ClassNotFoundException ex) {
        try {
            Class targetEntityClass = generateDummyClass(jpaProperty.getTargetEntity());
            oneToMany.param("targetEntity", targetEntityClass);
        } catch (CannotCompileException compileEx) {
            throw ex;
        }
    }
}

generateDummyClass使用 javaassist 在运行时创建类对象的方法:

private Class<?> generateDummyClass(String fullQualifedClassName)
        throws IOException, CannotCompileException {

    ClassPool pool = ClassPool.getDefault();
    pool.insertClassPath(new ClassClassPath(this.getClass()));
    CtClass ctClass = pool.makeClass(fullQualifedClassName);
    Class<?> clazz = ctClass.toClass();
    return clazz;
}

我们得到一个java源代码文件:

@OneToMany(targetEntity = org.foo.Bar.class)
private Set<Bar> bars = new HashSet<Bar>();
于 2013-06-27T11:13:36.683 回答