用于生成Java源文件的Java API
我正在寻找一个生成Java源文件的框架 类似于以下API:用于生成Java源文件的Java API,java,eclipse,code-generation,Java,Eclipse,Code Generation,我正在寻找一个生成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);
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个答案。。。和
我在我的解决方案中使用了:-)如果您真的需要源代码,我不知道任何生成源代码的东西。但是,您可以使用或直接创建.class文件
您可能可以从这些代码生成源代码,但我只使用它们生成字节码。该项目可用于生成源代码。我不认为它的API与您描述的完全一样,但每次我听说一个项目进行Java源代码生成时,他们都使用JET或一个自制工具。我自己是为了一个模拟生成器工具而做的。这是一项非常简单的任务,即使您需要遵循Sun的格式化准则。我打赌你会更快地完成代码,然后在互联网上找到符合你目标的东西
您基本上已经自己概述了API。现在就用实际代码填充它 另一种选择是EclipseJDT的AST,如果您需要重写任意Java源代码,而不仅仅是生成源代码,它是很好的选择。
(我相信它可以独立于eclipse使用)。我不知道有什么库,但您可能只需要一个通用模板引擎。还有,我个人对有很好的经验,Sun提供了一个名为CodeModel的API,用于使用API生成Java源文件。这不是最容易获得信息的事情,但它就在那里,而且工作得非常好 获取它的最简单方法是作为JAXB 2 RI的一部分—java生成器的XJC模式使用CodeModel生成其java源代码,它是XJC JAR的一部分。您可以将其仅用于代码模型
从使用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);
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;
public class Bar {
int foo() {
return 5;
}
}
package foo;
import java.util.Set;
class Foo<X> {
void MISSING(){
x();
}
}
通过Eclipse JDT的AST找到解决方案
谢谢 例如,使用此代码:
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);
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;
public class Bar {
int foo() {
return 5;
}
}
package foo;
import java.util.Set;
class Foo<X> {
void MISSING(){
x();
}
}
package-foo;
导入java.util.Set;
福班{
void缺失(){
x();
}
}
还有。它由ANTLR的作者编写,功能非常强大。这取决于你想做什么。代码生成本身就是一个主题。如果没有特定的用例,我建议查看velocity代码生成/模板库。另外,如果您离线生成代码,我建议使用ArgoUML之类的工具从UML图/对象模型转换为Java代码。我构建了一个非常类似于您理论上的DSL的工具,称为“sourcegen”,但从技术上讲,它不是我编写的ORM的UTI项目。DSL看起来像:
@Test
public void testTwoMethods() {
GClass gc = new GClass("foo.bar.Foo");
GMethod hello = gc.getMethod("hello");
hello.arguments("String foo");
hello.setBody("return 'Hi' + foo;");
GMethod goodbye = gc.getMethod("goodbye");
goodbye.arguments("String foo");
goodbye.setBody("return 'Bye' + foo;");
Assert.assertEquals(
Join.lines(new Object[] {
"package foo.bar;",
"",
"public class Foo {",
"",
" public void hello(String foo) {",
" return \"Hi\" + foo;",
" }",
"",
" public void goodbye(String foo) {",
" return \"Bye\" + foo;",
" }",
"",
"}",
"" }),
gc.toCode());
}
它还做了一些整洁的事情,比如“自动组织导入”参数/返回类型中的任何FQCN,自动修剪此codegen运行中未触及的任何旧文件,正确缩进内部类,等等
其思想是生成的代码应该看起来很漂亮,没有警告(未使用的导入等),就像代码的其余部分一样。这么多生成的代码读起来很难看…太可怕了
无论如何,文档并不多,但我认为API非常简单/直观。如果有人感兴趣,Maven回购协议是有效的。示例:
1/
二,/
有一个新项目。基于模板的代码生成器。您可以使用编写自定义模板,并根据java反射生成文件。这是生成任何文件的最简单方法。您可以通过生成AspectJ文件、基于JPA注释的SQL、基于枚举的插入/更新等来生成getter/settest/toString
模板示例:
package ${cls.package.name};
public class ${cls.shortName}Builder {
public static ${cls.name}Builder builder() {
return new ${cls.name}Builder();
}
<% for(field in cls.fields) {%>
private ${field.type.name} ${field.name};
<% } %>
<% for(field in cls.fields) {%>
public ${cls.name}Builder ${field.name}(${field.type.name} ${field.name}) {
this.${field.name} = ${field.name};
return this;
}
<% } %>
public ${cls.name} build() {
final ${cls.name} data = new ${cls.name}();
<% for(field in cls.fields) {%>
data.${field.setter.name}(this.${field.name});
<% } %>
return data;
}
}
package${cls.package.name};
公共类${cls.shortName}Builder{
公共静态${cls.name}Builder(){
返回新的${cls.name}Builder();
}
私有${field.type.name}${field.name};
public${cls.name}Builder${field.name}(${field.type.name}${field.name}){
这个${field.name}=${field.name};
归还这个;
}
public${cls.name}build(){
final${cls.name}data=new${cls.name}();
data.${field.setter.name}(this.${field.name});
返回数据;
}
}
您可以使用Roaster()生成代码
以下是一个例子:
JavaClassSource source = Roaster.create(JavaClassSource.class);
source.setName("MyClass").setPublic();
source.addMethod().setName("testMethod").setPrivate().setBody("return null;")
.setReturnType(String.class).addAnnotation(MyAnnotation.class);
System.out.println(source);
将显示以下输出:
public class MyClass {
private String testMethod() {
return null;
}
}
下面是一个JSON到POJO的项目,看起来很有趣:
你的问题非常笼统,你的问题领域真的如此笼统吗?你能更具体地说明你的问题领域吗?例如,我编写了代码生成工具来生成特定问题的代码,如消除重复的异常类代码,或消除枚举中的重复。@Vlookward:您可以将问题中的答案作为下面两个单独的答案移动。然后在每个问题上添加一个链接。@Banengusk:谢谢你的提问,节省了我搜索互联网最黑暗部分的时间@Skffman:伟大的发现-你让另一个开发人员在他即将到来的任务中更加轻松:)这样的回答解决了C++的问题,而不是java,但是答案也适用于java。呵呵。。。如果没有找到框架,那么我将编写它。我希望有很多功能,所以我不会在一个上午得到它…太好了!!一个抽象的语法树就是我要找的。。。现在