【问题标题】:Can I add a method to a class from a compile time annotation?我可以从编译时注释向类添加方法吗?
【发布时间】:2016-12-22 18:39:48
【问题描述】:

如果我创建一个自定义注解(例如:@SaveFuncName("saveMe") 将添加一个名为 saveMe() 的方法以及我的处理器生成的一些代码),javac 编译器可以使用我的注解处理器向类添加一个方法吗?还是只能创建一个不同的类?

【问题讨论】:

    标签: java annotations java-compiler-api


    【解决方案1】:

    或者我可以只创建一个不同的类吗?

    没错。现有的 API 不允许我们修改现有的类,只能生成新的类。

    从技术上讲,如果你想做一些 hacky 的东西,可以使用内部 Javac API 直接修改抽象语法树,但这不适合胆小的人。例如,TypeElement 这样的对象实际上是直接来自 Javac 的符号,被接口隐藏起来。语法树也可以通过compiler tree API 以只读模式获得。我们可以抛弃接口并以这种方式修改代码。这就是例如Project Lombok 有效。

    (但我不建议这样做。我主要是在解释它,因为 Lombok 是存在的,所以看起来修改类是可能的。)

    最简单的解决方案是使用例如生成超类。 saveMe() 方法并扩展它或生成一个实用程序类并委托给它。 (也建议here。)

    【讨论】:

    • 由于 Oracle 在 2017 年 5 月的“Java 杂志”中介绍了 Lombok……这是否意味着他们支持 hacky 的东西,或者会考虑允许 APT 更改当前文件?阅读这篇文章时,这个问题把我带到了这里,因为龙目岛似乎就是这样做的。但我想没有优雅的方法可以将它构建到 APT API 中,无论如何你都需要编辑 AST。
    • @Stroboskop 这很 hacky,因为它没有文档,所以你必须去阅读 javac 源代码才能弄清楚这些东西是如何工作的。可能那篇文章的作者只是不知道龙目岛在幕后做什么。 Lombok 有他们自己的简介,如果你想看看他们怎么说:jnb.ociweb.com/jnb/jnbJan2010.html#controversy 我个人希望修改 AST,或者至少只是添加方法,作为一项功能添加,但我怀疑它会很快发生。跨度>
    猜你喜欢
    • 1970-01-01
    • 2018-10-28
    • 2013-05-03
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 2011-10-12
    相关资源
    最近更新 更多