javapoet:MethodSpec.Builder.returns()生成错误

时间:2018-08-22 15:50:22

标签: java android annotations javapoet

我想从接口生成一个类。 我的界面是:

@Annotation
interface Object {
    String getName();
}

我希望这样:

public final class ObjectGenerated implements Object {
  public String getName() {
    return "my code";
  }
}

类处理器是:

@AutoService(Processor.class)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class Processor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {

        for (Element element : roundEnvironment.getElementsAnnotatedWith(Annotation.class)) {

            if (element.getKind() != ElementKind.INTERFACE) {
                messager.printMessage(Diagnostic.Kind.ERROR, "Can be applied to class.");
                return false;
            }

            generateClass(element);
        }

        return true;
    }

    private void generateClass(Element element) {

        try {
            String className = element.getSimpleName().toString();
            String pack = processingEnv.getElementUtils().getPackageOf(element).toString();
            String fileName = className + "Generated";

            TypeSpec.Builder classBuilder = TypeSpec
                    .classBuilder(fileName)
                    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                    .addSuperinterface(ClassName.get(element.asType()));

            for (Element elementMethod : element.getEnclosedElements()) {
                MethodSpec intentMethod = MethodSpec
                        .methodBuilder(elementMethod.getSimpleName().toString())
                        .addModifiers(Modifier.PUBLIC)
                        .addStatement("return $S", "my code")
                        .returns(ClassName.get(elementMethod.asType())) //this generate error
                        .build();
                classBuilder.addMethod(intentMethod);
            }

            JavaFile.builder(pack, classBuilder.build()).build().writeTo(filer);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return ImmutableSet.of(Annotation.class.getCanonicalName());
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
}

错误是: java.lang.IllegalArgumentException:意外的类型镜像:()java.lang.String

我可能做错了什么。 在我的情况下,如何从界面中获取“类型”为String并在MethodSpec.returns中使用它?

谢谢。

1 个答案:

答案 0 :(得分:0)

将您的Element投射到ExecutableElement并使用其getReturnType()

尤其是:

    for (Element elementMethod : element.getEnclosedElements()) {
       if (elementMethod.getKind() != ElementKind.METHOD) {
           //skip non-method elements like final fields
           continue;
       }
       ExecutableElement method = (ExecutableElement)elementMethod; //cast
       MethodSpec intentMethod = MethodSpec
                .methodBuilder(method.getSimpleName().toString())
                .addModifiers(Modifier.PUBLIC)
                .addStatement("return $S", "my code")
                .returns(ClassName.get(method.getReturnType())) //should be ok now
                .build();
       classBuilder.addMethod(intentMethod);
    }