Kotlin反射无法获取@JsonProperty注解的原因及解决方法咨询
问题原因与解决方案
1 @Column与@JsonProperty的核心差异
两者的表现差异本质是Kotlin编译器的注解默认映射规则不同导致的:
- Kotlin对JPA规范的
@Column等原生支持的平台注解有特殊适配:当该注解写在主构造器的属性参数上时,编译器会自动将注解同步到生成的类字段、getter方法等位置,因此直接读取字段注解可以正常获取。 @JsonProperty不属于Kotlin默认适配的平台注解:写在主构造器参数上时,注解默认仅标注在构造器参数本体上,不会同步到生成的类字段,因此直接读取字段的注解列表返回为空。
注:@JsonProperty本身的保留策略为RUNTIME,本身是支持运行时反射读取的,仅存在标注位置不符合预期的问题
2 正确获取@JsonProperty的两种方案
方案1:显式指定注解作用目标(推荐)
在@JsonProperty前加field:前缀,强制将注解标注到生成的类字段上,原有反射代码无需修改即可正常运行:
class SomeClass( @field:JsonProperty("trans_name") val transactionName: String, @field:JsonProperty("trans_dtime") val transactionDateTime: String // 其他属性 )
方案2:修改反射逻辑,从构造器参数读取注解
如果不想修改原有类的注解写法,可以调整反射代码直接从主构造器的参数中读取注解:
// Kotlin反射方式(需引入与Kotlin版本匹配的kotlin-reflect依赖) val jsonProps = SomeClass::class.primaryConstructor!!.parameters .mapNotNull { param -> param.findAnnotation<JsonProperty>()?.value?.let { it to param.name } } // Java反射方式(无需额外依赖) val constructor = SomeClass::class.java.declaredConstructors.first() val jsonProps = constructor.parameterAnnotations.zip(constructor.parameters.map { it.name }) .mapNotNull { (annotations, paramName) -> annotations.filterIsInstance<JsonProperty>().firstOrNull()?.value?.let { it to paramName } }
内容的提问来源于stack exchange,提问作者JoonT
相关产品推荐
相关产品推荐

