如何在注解处理器中读取嵌套注解的Class[]为List<TypeMirror>
解决注解处理器中嵌套注解的MirroredTypeException问题
这是注解处理器开发里非常常见的一个坑——当你试图直接调用注解的value()方法获取Class<?>[]时,会抛出MirroredTypeException,本质原因是注解处理器运行在编译过程中,此时相关类还没完成编译,JVM无法创建对应的Class实例,只能通过TypeMirror来获取类型信息。针对你这种嵌套注解的结构,我们需要通过AnnotationMirror和AnnotationValue来逐层解析,而不是直接调用注解代理的方法。
核心思路
不要直接调用ParentAnnotation.value()或者ChildAnnotation.value(),而是通过注解处理器提供的ProcessingEnvironment工具,从被标注的Element(比如你的Sample类对应的TypeElement)上获取AnnotationMirror,再逐层解析嵌套的注解属性值,最终把所有类类型转换成TypeMirror收集起来。
代码实现
// 假设你已经获取到了被@ParentAnnotation标注的TypeElement,比如叫sampleElement TypeElement sampleElement = ...; // 第一步:找到ParentAnnotation对应的AnnotationMirror Optional<? extends AnnotationMirror> parentAnnotationOpt = sampleElement.getAnnotationMirrors().stream() .filter(am -> am.getAnnotationType().toString().equals(ParentAnnotation.class.getName())) .findFirst(); if (parentAnnotationOpt.isPresent()) { AnnotationMirror parentAm = parentAnnotationOpt.get(); ProcessingEnvironment env = ...; // 你的Processor里的processingEnv Elements elementUtils = env.getElementUtils(); // 第二步:获取ParentAnnotation的value属性(ChildAnnotation数组) ExecutableElement parentValueMethod = elementUtils.getElementByName("value"); AnnotationValue childAnnotationsValue = parentAm.getElementValues().get(parentValueMethod); // 转换为ChildAnnotation对应的AnnotationValue列表 List<? extends AnnotationValue> childAnnotationValues = (List<? extends AnnotationValue>) childAnnotationsValue.getValue(); List<TypeMirror> allTypeMirrors = new ArrayList<>(); // 第三步:遍历每个ChildAnnotation for (AnnotationValue childAv : childAnnotationValues) { AnnotationMirror childAm = (AnnotationMirror) childAv.getValue(); // 获取ChildAnnotation的value属性(Class<?>数组) ExecutableElement childValueMethod = elementUtils.getElementByName("value"); AnnotationValue classesValue = childAm.getElementValues().get(childValueMethod); // 转换为每个Class对应的AnnotationValue列表 List<? extends AnnotationValue> classTypeValues = (List<? extends AnnotationValue>) classesValue.getValue(); // 第四步:把每个元素转换成TypeMirror并收集 for (AnnotationValue classAv : classTypeValues) { TypeMirror typeMirror = (TypeMirror) classAv.getValue(); allTypeMirrors.add(typeMirror); } } // 现在allTypeMirrors就是你要的所有类对应的TypeMirror列表了 // 可以用typeMirror做后续处理,比如获取全类名:elementUtils.getBinaryName((TypeElement) env.getTypeUtils().asElement(typeMirror)) }
关键说明
AnnotationMirror是注解在编译期的镜像表示,包含了注解的类型和所有属性值AnnotationValue用来表示注解属性的具体值,对于数组类型,它的getValue()会返回一个List<? extends AnnotationValue>- 整个过程完全基于编译期的类型信息(
TypeMirror),不会触发MirroredTypeException,因为我们没有尝试创建任何Class实例
内容的提问来源于stack exchange,提问作者Ahmad Bawaneh
相关产品推荐
相关产品推荐

