You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何@CustomGetter注解未为ExampleClass生成getValue方法?

核心问题分析

你的注解处理器当前生成的是独立的新类(比如ExampleClassGenerated),而非为ExampleClass本身添加方法。Java标准注解处理器(APT)无法直接修改已存在的类文件,只能生成新的类资源。这就是ExampleClass没有getValue()方法的根本原因。

同时,你的Maven配置存在疏漏,可能导致注解处理器无法在编译阶段被正确触发执行。


解决方案

1. 调整处理器逻辑:让原类间接拥有目标方法

由于APT不能修改原类,我们可以通过生成带默认方法的接口或生成父类的方式,让被注解类自动获得getValue()方法。这里推荐接口默认方法的实现(Java 8+支持):

修改处理器的generateGetValueMethod方法

private void generateGetValueMethod(TypeElement classElement) {
    String className = classElement.getSimpleName().toString();
    String packageName = processingEnv.getElementUtils().getPackageOf(classElement).getQualifiedName().toString();

    // 生成带默认方法的接口
    String interfaceName = "HasGetValue";
    
    String generatedCode = String.format(
            "package %s;\n\n" +
                    "public interface %s {\n" +
                    "    default String getValue() {\n" +
                    "        return \"Hello from getValue method!\";\n" +
                    "    }\n" +
                    "}\n",
            packageName, interfaceName
    );

    try {
        JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(
                packageName + "." + interfaceName, classElement);
        try (PrintWriter writer = new PrintWriter(fileObject.openWriter())) {
            writer.print(generatedCode);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

然后修改ExampleClass,让它实现这个生成的接口:

package ro.Gabriel.AnnotationTest;

@CustomGetter
public class ExampleClass implements HasGetValue {

}

这样ExampleClass就会继承接口的默认getValue()方法。

如果倾向于父类方式,可修改处理器生成父类,再让ExampleClass继承:

private void generateGetValueMethod(TypeElement classElement) {
    String className = classElement.getSimpleName().toString();
    String packageName = processingEnv.getElementUtils().getPackageOf(classElement).getQualifiedName().toString();

    String parentClassName = className + "Parent";
    
    String generatedCode = String.format(
            "package %s;\n\n" +
                    "public class %s {\n" +
                    "    public String getValue() {\n" +
                    "        return \"Hello from getValue method!\";\n" +
                    "    }\n" +
                    "}\n",
            packageName, parentClassName
    );

    try {
        JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(
                packageName + "." + parentClassName, classElement);
        try (PrintWriter writer = new PrintWriter(fileObject.openWriter())) {
            writer.print(generatedCode);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

对应的ExampleClass修改为:

@CustomGetter
public class ExampleClass extends ExampleClassParent {

}

2. 修正Maven配置,确保注解处理器正常执行

你使用了@AutoService,需要确保编译阶段能触发auto-service的处理器,同时自定义处理器能被正确识别。修改pom.xml:

配置maven-compiler-plugin指定注解处理器路径

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>8</source>
                <target>8</target>
                <!-- 配置注解处理器路径 -->
                <annotationProcessorPaths>
                    <path>
                        <groupId>com.google.auto.service</groupId>
                        <artifactId>auto-service</artifactId>
                        <version>1.0.1</version>
                    </path>
                    <!-- 加入当前项目作为处理器依赖(替换为你的项目groupId/artifactId/version) -->
                    <path>
                        <groupId>你的项目groupId</groupId>
                        <artifactId>你的项目artifactId</artifactId>
                        <version>你的项目版本</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

注意:如果自定义处理器和被注解类在同一模块,上述配置能确保处理器先被编译,再处理被注解类。另外,你手动创建的META-INF/services/javax.annotation.processing.Processor可以删除,@AutoService会在编译时自动生成该文件,避免冲突。

3. 验证编译流程

执行mvn clean compile,查看target目录:

  • 会生成HasGetValue.class(或ExampleClassParent.class)
  • ExampleClass编译后会包含getValue()方法的字节码

之后即可正常调用e.getValue()。


内容的提问来源于stack exchange,提问作者louiscarpenter3463

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:20:10