Java注释处理与源代码操作

Java注释处理与源代码操作,java,annotations,apt,java-compiler-api,Java,Annotations,Apt,Java Compiler Api,我一直在寻找以下要求的解决方案- 源文件是使用方法上的自定义注释编写的 方法主体需要根据注释进行一些更改 源文件不应更改,但编译器的输入应修改为源文件 我已经看过以下API- javax.annotation.processing-注释处理 javax.lang.model.*-注释处理和编译器树API中使用的语言模型 source.*-编译器树API 我想通过以下方式进行设计: 编写注释处理器 生成编译器树 在运行时编辑编译器树,而不影响原始源文件 将树提供给编译器 编译器树API似乎

我一直在寻找以下要求的解决方案-

  • 源文件是使用方法上的自定义注释编写的
  • 方法主体需要根据注释进行一些更改
  • 源文件不应更改,但编译器的输入应修改为源文件
我已经看过以下API-

  • javax.annotation.processing-注释处理
  • javax.lang.model.*-注释处理和编译器树API中使用的语言模型
  • source.*-编译器树API
我想通过以下方式进行设计:

  • 编写注释处理器
  • 生成编译器树
  • 在运行时编辑编译器树,而不影响原始源文件
  • 将树提供给编译器
  • 编译器树API似乎在允许访问 com.sun.source.tree.MethodTree

    但是,编译器树API似乎是只读的。 我不知道如何完成步骤3和4

    是否有任何API可供我采用以完成任务

    注意:我只寻找源代码操作技术。无运行时字节码操作/AOP


    环境:Java 6

    标准注释处理API不支持直接修改源代码。但是,修改源代码的一些效果可以通过生成注释类型的超类或子类来实现。下面的博客条目显示了此技术的一个示例:


    我建议您将所有源代码复制到一个单独的目录中,在那里修改代码,然后从临时路径进行构建。

    您可以按照下面的操作来完成3)和4)

    这将被处理为

    public String utf8ToString(byte[] bytes) {
        try {
            return new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw Lombok.sneakyThrow(e);
        }
    }
    
    public void run() {
        try {
            throw new Throwable();
        } catch (Throwable t) {
            throw Lombok.sneakyThrow(t);
        }
    }
    
    您可以在同一个Github/lombok站点上找到处理程序代码。

    通过基于上面的注释初始化字符串字段的值来修改源代码。也许你可以举个例子。
    public class SneakyThrowsExample implements Runnable {
        @SneakyThrows(UnsupportedEncodingException.class)
        public String utf8ToString(byte[] bytes) {
            return new String(bytes, "UTF-8");
        }
    
        @SneakyThrows
        public void run() {
            throw new Throwable();
        }
    }
    
    public String utf8ToString(byte[] bytes) {
        try {
            return new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw Lombok.sneakyThrow(e);
        }
    }
    
    public void run() {
        try {
            throw new Throwable();
        } catch (Throwable t) {
            throw Lombok.sneakyThrow(t);
        }
    }