如何在 Java 构建时动态生成带有注释的代码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7362659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 19:41:01  来源:igfitidea点击:

How to generate code dynamically with annotations at build time in Java?

javaannotationsgenerated-code

提问by Stephan

I'm looking for a solution for generating code. I have googled, searched on SO and some blogs but I didn't find a good solution.

我正在寻找生成代码的解决方案。我用谷歌搜索,搜索了 SO 和一些博客,但我没有找到一个好的解决方案。

I'd like to put an annotation on my class and at compilation time, some methods and properties would be automatically added to the class.

我想在我的类上添加注释,并且在编译时,一些方法和属性会自动添加到类中。

Key points of the solution I'm looking for :

我正在寻找的解决方案的关键点:

  • Generated code customizable (MANDATORY)
  • No external tool like apthave to be called (MANDATORY)
  • JDK only, no third-party framework (MANDATORYOPTIONAL)
  • Annotation name customizable (OPTIONAL)
  • 生成的代码可定制(强制性)
  • 无需apt调用外部工具(强制性)
  • 只有 JDK,没有第三方框架(强制性可选)
  • 注释名称可定制(可选)

For example :

例如 :

@Aliasable
public class MyClass {
//Some properties

// Contructor ...

// Some methods
}

My class would look like this after compilation :

编译后我的类看起来像这样:

public class MyClass {
   //Some properties
   private String alias;

   // Contructor ...

   // Some methods
   public String getAlias() {
      return alias;
   }

   public void setAlias(String alias) {
      this.alias=alias;
   }
}

EDIT:
Finally, I turned my third requirement from MANDATORY to OPTIONAL and choosed project Lombok(easy integration with Maven and Eclipse, virtually no work to do for using it).

编辑:
最后,我将我的第三个要求从 MANDATORY 变成了 OPTIONAL 并选择了Lombok 项目(与 Maven 和 Eclipse 轻松集成,几乎不需要使用它)。

采纳答案by Hymanrabbit

Have a look at Project Lombok. It generates code as you ask when you write:

看看龙目岛项目。当您编写时,它会按照您的要求生成代码:

public class MyClass {
  @Getter @Setter private String alias;
}

It also does a lot more if you need it. I know you asked for no external tools, but you would basically be recreating this.

如果您需要它,它还可以做更多的事情。我知道您不需要外部工具,但您基本上会重新创建它。

回答by kapex

The annotation processing toolhas been integrated in javacsince version 1.6 and is part of the JDK. So there is no need for external tools when using the Pluggable Annotation API. You can generate any code by analysing custom annotations or method/parameter/field/class declarations using the Mirror API.

注释处理工具已集成的javac自1.6版本是JDK的一部分。因此在使用Pluggable Annotation API时不需要外部工具。您可以通过使用Mirror API分析自定义注释或方法/参数/字段/类声明来生成任何代码。

The annotation processor API says you shouldn't change existing classes. Instead you should generate subclasses of existing classes and create extension methods on those subclasses.

注释处理器 API 说你不应该改变现有的类。相反,您应该生成现有类的子类并在这些子类上创建扩展方法。

It seems to be possible to change classes anyway (e.g. by using bytecode manipulation libraries) though that would in contrast to the specification and could lead to issues with other annotation processors and may not work with all compilers in the same way.

似乎无论如何都可以更改类(例如,通过使用字节码操作库),尽管这与规范相反,并可能导致其他注释处理器出现问题,并且可能无法以相同的方式与所有编译器一起使用。

回答by Benjamin Udink ten Cate

I use XML and XSLT to generate code. It is used for EJB, Logic and the CRUD part of the views. It isnt gerated at runtime but instead on the buildserver. Developers can generate the code manually for well development purposes. This is done with the same command ANT uses on the buildserver.

我使用 XML 和 XSLT 来生成代码。它用于 EJB、逻辑和视图的 CRUD 部分。它不是在运行时生成,而是在构建服务器上生成。开发人员可以出于开发目的手动生成代码。这是使用 ANT 在构建服务器上使用的相同命令完成的。

Because the generation is with XML and XSLT it is highly customizable.

因为生成是使用 XML 和 XSLT,所以它是高度可定制的。

If you google Java code generation with XSLTyou will run into alot of examples. Please note that this technique dates from ~2000 and thus probably has been preceded by now by easier solutions.

如果你谷歌Java code generation with XSLT你会遇到很多例子。请注意,这项技术可以追溯到 2000 年左右,因此现在可能已经有了更简单的解决方案。