Java API生成Java源文件

时间:2020-03-06 14:36:08  来源:igfitidea点击:

我正在寻找一个生成Java源文件的框架。

类似于以下API:

X clazz = Something.createClass("package name", "class name");
clazz.addSuperInterface("interface name");
clazz.addMethod("method name", returnType, argumentTypes, ...);

File targetDir = ...;
clazz.generate(targetDir);

然后,应该在目标目录的子目录中找到一个Java源文件。

有人知道这样的框架吗?

编辑:

  • 我真的需要源文件。
  • 我也想填写这些方法的代码。
  • 我正在寻找一个高级抽象,而不是直接的字节码操作/生成。
  • 我还需要对象树中的"类的结构"。
  • 问题域很一般:生成大量非常不同的类,而没有"通用结构"。

解决方案
我已经根据答案发布了2个答案……使用CodeModel和Eclipse JDT。

我在解决方案中使用了CodeModel :-)

解决方案

如果我们确实需要该来源,那么我什么都不知道会产生该来源。但是,我们可以使用ASM或者CGLIB直接创建.class文件。

我们也许可以从这些文件生成源,但是我只用它们来生成字节码。

Eclipse JET项目可用于生成源代码。我认为它的API与我们描述的API并不完全相同,但是每次我听到一个进行Java源代码生成的项目时,他们都使用JET或者本地开发的工具。

我自己是为模拟生成器工具来做的。即使我们需要遵循Sun格式化准则,这也是一项非常简单的任务。我敢打赌,我们会更快地完成执行该代码的代码,然后在Internet上找到适合我们目标的内容。

我们基本上已经自己概述了API。立即填写实际代码!

另一个选择是Eclipse JDT的AST,如果我们需要重写任意Java源代码而不是仅生成源代码,则该方法很好。
(我相信它可以独立于日食使用)。

不知道一个库,但是通用模板引擎可能就是我们所需要的。其中有一堆,我个人在FreeMarker上有很好的经验

Sun提供了一个称为CodeModel的API,用于使用API​​生成Java源文件。这不是最容易获得信息的事情,但是它就在那里而且效果非常好。

掌握它的最简单方法是作为JAXB 2 RI的一部分,XJC模式到Java生成器使用CodeModel生成其Java源,它也是XJC jar的一部分。我们可以仅将其用于CodeModel。

从http://codemodel.java.net/获取

用CodeModel找到的解决方案
谢谢,夫。

例如,使用以下代码:

JCodeModel cm = new JCodeModel();
JDefinedClass dc = cm._class("foo.Bar");
JMethod m = dc.method(0, int.class, "foo");
m.body()._return(JExpr.lit(5));

File file = new File("./target/classes");
file.mkdirs();
cm.build(file);

我可以得到以下输出:

package foo;
public class Bar {
    int foo() {
        return  5;
    }
}

Eclipse JDT的AST找到了解决方案
谢谢,吉尔斯。

例如,使用以下代码:

AST ast = AST.newAST(AST.JLS3);
CompilationUnit cu = ast.newCompilationUnit();

PackageDeclaration p1 = ast.newPackageDeclaration();
p1.setName(ast.newSimpleName("foo"));
cu.setPackage(p1);

ImportDeclaration id = ast.newImportDeclaration();
id.setName(ast.newName(new String[] { "java", "util", "Set" }));
cu.imports().add(id);

TypeDeclaration td = ast.newTypeDeclaration();
td.setName(ast.newSimpleName("Foo"));
TypeParameter tp = ast.newTypeParameter();
tp.setName(ast.newSimpleName("X"));
td.typeParameters().add(tp);
cu.types().add(td);

MethodDeclaration md = ast.newMethodDeclaration();
td.bodyDeclarations().add(md);

Block block = ast.newBlock();
md.setBody(block);

MethodInvocation mi = ast.newMethodInvocation();
mi.setName(ast.newSimpleName("x"));

ExpressionStatement e = ast.newExpressionStatement(mi);
block.statements().add(e);

System.out.println(cu);

我可以得到以下输出:

package foo;
import java.util.Set;
class Foo<X> {
  void MISSING(){
    x();
  }
}

也有StringTemplate。它是由ANTLR的作者撰写的,功能非常强大。