如何通过Element或TypeMirror获取Class<?>?注解处理器类获取问题
注解处理器中处理Class类型成员的方法
一、单个Class<?>类型成员的处理
别想着直接拿运行时的Class<?>对象——注解处理器跑在编译阶段,目标类可能还没编译完,根本没法被类加载器加载。但你可以拿到对应类的编译期元数据(比如TypeElement、全限定类名),具体步骤:
- 从你要处理的目标
Element(类、方法、字段都行)上,拿到对应注解的AnnotationMirror - 遍历
AnnotationMirror的元素值,找到tableClass这个成员对应的AnnotationValue - 从
AnnotationValue里取出TypeMirror,转成DeclaredType - 用
Elements工具类把DeclaredType转成TypeElement,就能拿到类的全限定名等信息
示例代码:
// 假设你已经拿到了要处理的目标Element Element targetElement = ...; // 获取自定义注解的AnnotationMirror AnnotationMirror annotationMirror = getAnnotationMirror(targetElement, YourAnnotation.class); // 拿到tableClass成员的值 AnnotationValue tableClassValue = getAnnotationValue(annotationMirror, "tableClass"); // 取出TypeMirror并转成DeclaredType TypeMirror typeMirror = (TypeMirror) tableClassValue.getValue(); DeclaredType declaredType = (DeclaredType) typeMirror; // 获取类的元数据TypeElement TypeElement tableTypeElement = (TypeElement) declaredType.asElement(); // 拿到全限定类名,后续生成代码时能用 String className = tableTypeElement.getQualifiedName().toString(); // 辅助方法:找指定注解的AnnotationMirror private AnnotationMirror getAnnotationMirror(Element element, Class<? extends Annotation> annotationClass) { for (AnnotationMirror mirror : element.getAnnotationMirrors()) { if (mirror.getAnnotationType().toString().equals(annotationClass.getCanonicalName())) { return mirror; } } return null; } // 辅助方法:找注解中指定成员的值 private AnnotationValue getAnnotationValue(AnnotationMirror mirror, String memberName) { for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : mirror.getElementValues().entrySet()) { if (entry.getKey().getSimpleName().toString().equals(memberName)) { return entry.getValue(); } } return null; }
二、Class<?>[]类型成员的处理
数组类型的处理逻辑和单个的差不多,只是AnnotationValue的getValue()返回的是List<AnnotationValue>,每个元素对应数组里的一个Class类型,步骤如下:
- 同样先拿到
AnnotationMirror和目标成员的AnnotationValue - 把
getValue()的结果转成List<AnnotationValue>,逐个遍历 - 每个元素重复单个类型的处理流程,拿到对应的元数据
示例代码:
// 拿到tableClasses(Class<?>[]类型)成员的值 AnnotationValue tableClassesValue = getAnnotationValue(annotationMirror, "tableClasses"); // 数组类型对应List<AnnotationValue> List<? extends AnnotationValue> classValues = (List<? extends AnnotationValue>) tableClassesValue.getValue(); List<String> classNames = new ArrayList<>(); for (AnnotationValue value : classValues) { TypeMirror typeMirror = (TypeMirror) value.getValue(); DeclaredType declaredType = (DeclaredType) typeMirror; TypeElement typeElement = (TypeElement) declaredType.asElement(); classNames.add(typeElement.getQualifiedName().toString()); }
重要提醒
- 编译阶段只能拿编译期的元数据,不能直接获取运行时的
Class实例,要是你需要在生成的代码里用这些类,直接用全限定类名就行,运行时会自动加载。
内容的提问来源于stack exchange,提问作者Andelic47 Aaron
相关产品推荐
相关产品推荐

