Java 在编译时添加/生成方法

Java 在编译时添加/生成方法,java,dynamic-code,Java,Dynamic Code,我目前正在构建一个API,我将要求许多开发人员使用它。其中大部分都很简单,但有几个api调用本质上很复杂,但应该以样板的方式使用 我想做的是在类内部生成样板代码,可能是通过标记一些注释,但是这些生成的方法可以在Eclipse/IntelliJ中供开发人员查看。我研究了Javassist,但不确定运行时性质是否是一件好事。我宁愿采用编译时方法 如果可能,我希望实现的代码被隐藏(即,我不希望开发人员尝试更改生成的方法的代码,因为它们在重新编译时会被过度编写) 这一切都是为了向开发人员和维护人员隐藏处

我目前正在构建一个API,我将要求许多开发人员使用它。其中大部分都很简单,但有几个api调用本质上很复杂,但应该以样板的方式使用

我想做的是在类内部生成样板代码,可能是通过标记一些注释,但是这些生成的方法可以在Eclipse/IntelliJ中供开发人员查看。我研究了Javassist,但不确定运行时性质是否是一件好事。我宁愿采用编译时方法

如果可能,我希望实现的代码被隐藏(即,我不希望开发人员尝试更改生成的方法的代码,因为它们在重新编译时会被过度编写)


这一切都是为了向开发人员和维护人员隐藏处理的复杂性,并将其保留在核心框架代码中。

Java编译器支持。您可以编写注释,根据注释的要求生成代码。

这个问题有两个部分。首先,您希望让开发人员可以使用API,而无需编写/公开样板实现。其次,您希望自动化样板代码的生成

如果您愿意承认正在使用某个框架,则无需生成代码/字节码即可:

  • 对于每个重要概念,编写一个完全定义API的接口
  • 现在编写相应的类,该类不实现接口,但与非样板API的方法签名相匹配。您可能需要使用命名约定来将它们配对
  • 编写一个使用Java代理生成接口实现的工厂。只要可能,代理将委托给实现。样板代码将直接在实现处理程序中实现
  • 您可能需要各种类型的调用处理程序,在这种情况下,请考虑那些对于的命名约定。
  • 如果您不喜欢逻辑和接口之间未经检查的耦合,请提取一个不包含样板API的超级接口
  • 使用这些构造的逻辑将按接口名称请求实例;工厂将知道如何实例化底层逻辑实例和调用处理程序
另一方面,如果您不希望开发人员记住框架的存在,或者您需要样板实现来访问逻辑的内部,那么您需要执行代码生成/字节码操作

操作本身可以使用自定义类加载器完成,也可以在初始类加载期间使用。但是如何让开发人员可以使用API呢?以下是一些想法:

  • 使实现类抽象,并声明将在其中生成样板代码的抽象方法

  • 编写样板方法的存根实现(即在
    void
    方法中不执行任何操作;在所有其他方法中抛出
    RuntimeException

  • 执行类似于GoogleWebToolkit的操作,并将样板方法声明为
    native
    。这类似于标记方法
    abstract
    ,但允许您做一些事情,例如使类
    成为final


生成的代码非常标准。例如,JAXB有XJC,它将XML模式编译成Java类,它位于Java标准库中。我认为这其中“有趣”的部分是将生成代码集成到构建系统中-我使用Maven,这使得这一过程非常简单。我将从实现您想要的反射开始,并在需要时使用生成的代码对其进行优化。不幸的是,这只允许创建新的源文件,而不是重建带注释的源文件。