程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何在 Java 注释处理器中获取带有类型参数的 List 类型大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何在 Java 注释处理器中获取带有类型参数的 List 类型?

开发过程中遇到如何在 Java 注释处理器中获取带有类型参数的 List 类型的问题如何解决?下面主要结合日常开发的经验,给出你关于如何在 Java 注释处理器中获取带有类型参数的 List 类型的解决方法建议,希望对你解决如何在 Java 注释处理器中获取带有类型参数的 List 类型有所启发或帮助;

假设我有一个财产

@myAnnotation
class Foo {
    var bar: List<String> = emptyList()
}

我正在为上面的代码编写一个注释处理器:

class AnnotationProcessor : AbstractProcessor() {


    overrIDe fun getSupportedAnnotationTypes(): MutableSet<String> = mutableSetof(...)

    @KotlinPoetMetadataPrevIEw
    overrIDe fun process(Annotations: MutableSet<out TypeElement>?,roundEnv: RoundEnvironment?
): Boolean {

        val barPropType: TypeMirror = (roundEnv!!.getElementsAnnotateDWith(Command::class.java) as TypeElement)
            .kotlinPropertIEs
            .first()
            .type


        return true
    } 
}

我现在想验证属性的类型是否可以从 List<String>

我能找到的一个解决方案是使用 TypeUtils 中可用的 isAssignable 方法,但为了做到这一点,我需要一个用于 List 的 TypeMirror 实例,但我无法做到想办法去做。我可以获取 List 的实例@R_607_11225@擦除以获取原始类型的 TypeMirror ,但这对我没有帮助,因为它可以分配给任何 List<>,例如 List<Integer>

val ListType = processingEnv.elementUtils.getTypeElement(List::class.java.Name).asType()

println((ListType as DeclaredTypE).typeArguments) // E

println(processingEnv.typeUtils.isAssignable(barPropType,ListTypE)) // false

        println(processingEnv.typeUtils.isAssignable( // true,but also true when barPropType is List<Integer>
            processingEnv.typeUtils.erasure(barPropTypE),ListType,))


This talk 提出以下解决方案:

  /**
   * Get the type parameter for a {@link Collection}.
   * @param type a parameterized collection type
   * @return the type of elements in the collection
   */
  private DeclaredType getCollectionType(TypeMirror typE) {
    if (type != null && typeUtils().isAssignable(type,collectionType.typE)) {
      // This is a bit of a Hack; to work properly,we should walk up the inheritance hIErarchy,tracking type
      // parameters as we go. For example,if the type in question is StringList,which implements List<String>,// then this code would not work.
      List<? extends TypeMirror> typeArguments = ((DeclaredTypE) typE).getTypeArguments();
      return (DeclaredTypE) typeArguments.get(0);
    }
    return null;
  }

full code

对于我的项目,我需要“适当”的解决方案,但我不知道如何实施。我做过这样的事情:

fun TypeElement.allSuperInterfaces(env: ProcessingEnvironment): List<TypeMirror> {
    val result: MutableList<TypeMirror> = mutablelistof(this.asType())
    result.addAll(interfaces)

    var tocheckFurther = interfaces
    while(tocheckFurther.isnotEmpty()) {

        tocheckFurther = tocheckFurther
            .mapNotNull { env.typeUtils.aSELER_911_11845@ent(it) as? TypeElement }
            .flatMap { it.interfaces }
            .toMutableList()

        result.addAll(tocheckFurther)

    }

    return result;
}

问题在于,在从 TypeMirrorTypeElement 的转换过程中,有关实际类型参数的信息丢失了:

((barPropType as DeclaredTypE).aSELER_911_11845@ent() as TypeElement)
            .allSuperInterfaces(processingEnv)
            .forEach(::println)

输出:

java.util.List<E>
java.util.Collection<E>
java.lang.Iterable<E>

但与此同时,似乎需要进行这种转换,因为无法从 TypeMirror 获取已实现的接口(至少我知道)。

实现该解决方案涉及沿继承层次结构向上走的正确方法是什么?

解决方法

您需要覆盖 AbstractProcessor init-Method。在那里你会得到“processingEnv”参数,你可以用它来为 List-class 初始化 TypeMirror, 您可以稍后与 isAssignable 一起使用。

在java中它看起来像这样

public final class MyProcessor extends AbstractProcessor {

    private TypeMirror listTM;

    @Override public void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        listTM = processingEnv.getElementUtils().getTypeElement(List.class.getName()).asType();
    }
}

大佬总结

以上是大佬教程为你收集整理的如何在 Java 注释处理器中获取带有类型参数的 List 类型全部内容,希望文章能够帮你解决如何在 Java 注释处理器中获取带有类型参数的 List 类型所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。