我想编写一个基本上调用静态泛型方法的CodeBlock
,但我用JavaPoet
得到的输出会产生编译错误。
例如,给定以下自动值类:
@AutoValue
public abstract class Test<T> {
public abstract Test1<String> o();
public abstract T p();
@AutoValue
public static abstract class Test1<T> {
public abstract T value();
public static <T> Test1<T> create(T value) {
return Test1.<T>builder()
.value(value)
.build();
}
public static <T> Builder<T> builder() {
return new AutoValue_ValueWithOperator.Builder<>();
}
public static <T> Builder<T> testBuilder() {
return builder();
}
@AutoValue.Builder
public abstract static class Builder<T> {
public abstract Builder<T> value(T value);
public abstract Test1<T> build();
}
}
}
现在说我想为testBuilder
生成Test1<String>
的调用(在测试中),我首先通过执行TypeName
来获取:{/ p>
TypeName elementReturnType = TypeName.get(someTypeMirror);
现在我做的时候:
CodeBlock.of("$T.testBuilder()" + ".build()", elementReturnType);
它生成的代码如下:
Test.Test1<String>.testBuilder().build();
这是错误的,正确的语法应该是:
Test.Test1.<String>testBuilder().build();
请注意泛型参数的位置...如何使用JavaPoet完成此操作?我可以通过生成的代码看到正确的类型,但它只是将通用参数放在错误的位置。
我的问题是,如何使用JavaPoet CodeBlock
向方法调用添加泛型参数?
答案 0 :(得分:0)
您只需要注意泛型类型是方法的一部分,不是类,因此在编写方法调用时,请尝试将泛型与编写方法的部分相关联调用
TypeName elementReturnType = TypeName.get(elementTypeMirror);
假设您有一个表示要调用的方法的元素:
ExecutableElement method = ...;
if (methodElement.getTypeParameters().isEmpty()) {
return CodeBlock.of("$T.$N().build()", elementReturnType, methodElement.getSimpleName());
}
String typeParams = MoreTypes
.asDeclared(returnType)
.getTypeArguments()
.stream()
.map(MoreTypes::asTypeElement)
.map(TypeElement::getQualifiedName)
.collect(Collectors.joining("<", ",", ">");
这将为您提供类型参数,您可以将其附加到方法名称(method.getSimpleName()
)。