kotlin - 如何让杰克逊接受 readvalue 的泛型?
问题描述
我正在对一段糟糕的代码进行一些重构,因为我有非常相似的函数:
fun getLogin(username: String) {
val uri = buildURI(BASE_URI, ApiRoute.GET_LOGIN.route, username)
val httpResponse = execRequest(uri, HttpMethod.GET)
val login: LoginResponse = mapper.readValue(httpResponse)
fun getUser(username: String) {
val uri = buildURI(BASE_URI, ApiRoute.GET_LOGIN.route, username)
val httpResponse = execRequest(uri, HttpMethod.GET)
val login: userResponse = mapper.readValue(httpResponse)
这些行之间的唯一区别是 call 的返回类型mapper.readValue(httpResponse)
。基于此,我编写了一个用于两种场景的新函数:
fun <T> getEvent(value: String, eventType: EventType): T {
val uri = buildURI(BASE_URI, eventType.route, value)
val httpResponse = execRequest(uri, HttpMethod.GET)
return mapper.readValue(httpResponse);
}
问题是:我不能使用“T”作为具体类型参数。如何编写一个将“通用”值传递给杰克逊的函数?
解决方案
由于类型擦除,泛型类型在运行时丢失。这就是为什么不能使用T
with readValue
,因为T
仅用于确保编译时类型安全,但在运行时不存在。
为了解决这个问题,你可以让你的函数inline
和泛型类型参数reified
,所以类型类将在调用站点获得:
inline fun <reified T> test(value: String): T {
return mapper.readValue(value, T::class.java)
}
或者,如果您使用 Jackson Kotlin 模块:
inline fun <reified T> test(value: String): T {
return mapper.readValue<T>(value)
}
我稍微简化了你的用例,但它的工作原理是一样的。
进一步阅读:
推荐阅读
- amazon-web-services - Ruby:调用不存在
- vue.js - bootstrap-vue 仅更改选项卡标题背景颜色
- python - 导入 object_detection/protos/image_resizer.proto 但未在 OS High Sierra 中使用 protobuf 编译的问题
- python - Jstor Web Scraping 返回空
- r - mle2 出错:3 个参数传递给 '('
- jsonschema - 如何使用可选的布尔属性作为需要另一个属性的提示?
- grep - 使用 grep 捕获操作系统名称
- prometheus - prometheus-node_exporter grafana:如何显示集群中所有节点的状态?包括幸存者和衣架
- javascript - Stack.Navigator 未显示后退按钮
- php - 如何使用一行代码进行 PHP 重定向