大佬教程收集整理的这篇文章主要介绍了如何在 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;
}
问题在于,在从 TypeMirror
到 TypeElement
的转换过程中,有关实际类型参数的信息丢失了:
((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,请注明来意。