javapoet: MethodSpec.Builder.returns() генерирует ошибку

Я хотел бы создать класс из интерфейса. Мой интерфейс:

@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 ?

Спасибо.


person vikey89    schedule 22.08.2018    source источник


Ответы (1)


Преобразуйте свой 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);
    }
person Kostiantyn    schedule 22.08.2018