Annotation Processor中如何获取被注解字段的实际类型
问题原因
Kotlin 编译到JVM平台时,接口中声明的var属性不会生成实际的 backing field(即Java语义中的类成员字段),只会自动生成两个对应的抽象方法:
- 无参getter方法:常规属性命名为
getXxx,如果属性名以is开头且类型为Boolean,getter名与属性名一致,返回值类型和属性声明类型完全一致 - 单参setter方法:命名为
setXxx,返回值固定为void,入参类型和属性类型一致
你当前识别到返回类型为void的元素本质是属性对应的setter方法,自然拿不到正确的属性类型。加上Java原生注解处理器API是基于JVM字节码结构设计的,无法直接识别Kotlin源码层面的属性概念,才会出现这个问题。
解决方法
方法1:按JVM方法规则过滤getter取返回类型
不需要额外依赖,直接通过方法签名特征过滤出getter,取返回值即可:
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(CustomAnnotation.class)) { // 接口里的属性注解最终会标记在生成的访问器方法上 if (annotatedElement.getKind() != ElementKind.METHOD) { continue; } ExecutableElement executableElement = (ExecutableElement) annotatedElement; // 跳过setter:返回void、有且仅有1个入参、方法名以set开头 if (executableElement.getReturnType().getKind() == TypeKind.VOID && executableElement.getParameters().size() == 1 && executableElement.getSimpleName().toString().startsWith("set")) { continue; } // 剩余的就是getter方法,返回值就是属性的真实类型 TypeMirror realPropertyType = executableElement.getReturnType(); // 本示例中这里拿到的就是Boolean类型 }
注意:如果属性是isXxx格式的Boolean类型,需要额外兼容:无入参、返回Boolean类型、方法名以is开头的方法也属于getter,不要误过滤。
方法2:解析Kotlin元数据直接获取属性信息
如果需要更稳定的逻辑、不想手动适配方法命名规则,可以引入Kotlin官方的kotlinx-metadata库,读取类上编译生成的@Metadata注解,直接解析出Kotlin源码层面声明的属性列表、属性类型、注解关联关系,完全不需要处理JVM层的方法映射逻辑,兼容性最好,不会被Kotlin版本的编译规则调整影响。
内容的提问来源于stack exchange,提问作者smplio
相关产品推荐
相关产品推荐

