首页 > 解决方案 > 如何使用 JavaPoet 构造具有自定义类型的枚举

问题描述

是否可以使用 JavaPoet 生成以下枚举类?

public enum EnumName {

  import com.sth.sth.SomeClass1;
  import com.sth.sth.SomeClass2;

  ITEM1(new CustomType<SomeClass1>("string1", "string 2", SomeClass1.class)),
  ITEM2(new CustomType<SomeClass2>("string1", "string 2", SomeClass2.class));

  EnumName(CustomType customType) {
    this.customType = customType;
  }

  private final CustomType customType;

  public CustomType getCustomType() {
    return customType;
  }
}

我可以创建所有东西,但我在 ITEM 中的初始化块方面遇到了巨大的困难。

我目前的代码是

TypeSpec.Builder typeSpecBuilder = TypeSpec.enumBuilder("EnumName")
                .addModifiers(PUBLIC)
                .addField(TypeVariableName.get("CustomType"), "customType", PRIVATE, FINAL)
                .addMethod(MethodSpec.constructorBuilder()
                                     .addParameter(TypeVariableName.get("CustomType"), "customType")
                                     .addStatement("this.$N = $N", "customType", "customType")
                                     .build())
                .addMethod(MethodSpec.methodBuilder("getCustomType")
                                     .addModifiers(PUBLIC)
                                     .addStatement("return customType")
                                     .returns(TypeVariableName.get("CustomType"))
                                     .build());
for (Model model : models) {
    typeSpecBuilder.addEnumConstant(prepareName(model), HERE I DO NOT KNOW HOW TO BUILD TypeSpec that would create what i need);
}

我能够创造这个

public enum EnumName {

  ITEM1("ITEM1"){
    @Override
    public CustomType getCustomType(){
      return new CustomType<SomeClass1>("string1", "string 2", SomeClass1.class));
    }
  },
  ITEM2("ITEM2"){
    @Override
    public CustomType getCustomType(){
      return new CustomType<SomeClass2>("string1", "string 2", SomeClass2.class));
    }
 };

  EnumName(customTypeName customTypeName) {
    this.customTypeName = customTypeName;
  }

  private final String customTypeName;

  public String getCustomTypeName() {
    return customTypeName;
  }

通过像这样调整循环:

for (Model model : models) {
    typeSpecBuilder.addEnumConstant(prepareName(model), TypeSpec.anonymousClassBuilder("$S", prepareName(model))
    .addMethod(MethodSpec.methodBuilder("getCustomType")
    .addAnnotation(Override.class)
    .addModifiers(PUBLIC)
    .addStatement(getInitStatement(model))
    .returns(TypeVariableName.get("CustomType"))
                            .build())
                    .build());
}

这部分没问题,但我不知道如何为这些类生成导入。

我更喜欢第一个选项

ITEM1(new CustomType<SomeClass1>("string1", "string 2", SomeClass1.class))

但如果无法完成,有人可以建议如何为第二个示例生成导入并调整周期?

非常感谢您的任何建议。

标签: javajavapoet

解决方案


如果有人对未来感兴趣,可以找到解决方案。

String fullyQualifiedClassName = getClassName();
if (fullyQualifiedClassName == null) {
  fullyQualifiedClassName = "Object";  //important if class was not found we need set to object -> otherwise there will not be imports for some reason
}
TypeName typeName = ClassName.bestGuess(fullyQualifiedClassName);
for (Model model : models) {
    typeSpecBuilder.addEnumConstant(prepareName(model), TypeSpec.anonymousClassBuilder("new CustomType<$T>($S, $S, $T.class)", typeName, string1, string2, typeName));
}

推荐阅读