Kotlin泛型JsonPatchMapper创建报错:无法使用T作为具体化类型参数
问题原因
Kotlin中非reified泛型参数会在运行时被类型擦除,类级泛型T不属于reified类型,因此无法直接通过T::class.java获取其Class对象,这就是报错的核心原因。
解决方案
提供两种适配场景的修复方案:
方案一:保留BiFunction接口,传入Class构造参数
通过在类的构造函数中接收目标类型的Class<T>,替代无法直接获取的T::class.java,同时保持对BiFunction接口的实现:
import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.github.fge.jsonpatch.JsonPatch import org.springframework.stereotype.Component import java.util.function.BiFunction @Component class JsonPatchMapper<T>(private val targetClass: Class<T>) : BiFunction<T, JsonPatch, T> { private val objectMapper = jacksonObjectMapper() override fun apply(targetBean: T, patch: JsonPatch): T { val targetNode = objectMapper.convertValue(targetBean, JsonNode::class.java) val patchedNode = patch.apply(targetNode) return objectMapper.treeToValue(patchedNode, targetClass) } }
使用方式
在Spring中为具体类型创建Bean:
@Bean fun userJsonPatchMapper(): JsonPatchMapper<User> { return JsonPatchMapper(User::class.java) }
注入时直接指定泛型类型即可:
@Autowired private lateinit var userPatchMapper: JsonPatchMapper<User>
方案二:改用reified泛型方法(更灵活)
放弃实现BiFunction,将泛型定义在方法级别并使用reified关键字,让编译器在编译期保留类型信息:
import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.github.fge.jsonpatch.JsonPatch import org.springframework.stereotype.Component @Component class JsonPatchMapper { private val objectMapper = jacksonObjectMapper() inline fun <reified T> apply(targetBean: T, patch: JsonPatch): T { val targetNode = objectMapper.convertValue(targetBean, JsonNode::class.java) val patchedNode = patch.apply(targetNode) return objectMapper.treeToValue(patchedNode, T::class.java) } }
使用方式
直接调用方法,编译器会自动推断泛型类型:
val patchedUser = jsonPatchMapper.apply(originalUser, jsonPatch)
方案对比
- 方案一:适合需要遵循
BiFunction函数式接口规范的场景,需为每个目标类型单独创建Bean。 - 方案二:无需额外创建Bean,调用更简洁灵活,适合大多数普通业务场景。
内容的提问来源于stack exchange,提问作者J.Kennsy
相关产品推荐
相关产品推荐

