Java API生成Java源文件
我正在寻找一个生成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的作者撰写的,功能非常强大。