首页 > 解决方案 > Kotlin 将泛型类型与泛型类型的包装类混合在一起

问题描述

我正在尝试在 Kotlin 中构建一个简单的 HttpClient。我使用内联函数来处理泛型类型,并使用这样的具体泛型类型:

inline fun <reified T> execute(path: String,
                               requestMethodString: HttpMethod,
                               data: String?,
                               callback: (response: T) -> Unit) {
    (...)
    callback(mapper.readValue(json.toString())) 
    //jackson using kotlin module reads type from what callback wants as 
    //callback(mapper.readValue<T>(json.toString())) 
    (...)
}

如果我像这样调用我的 HttpClient,这很有效:

HttpClient.get<HttpResponse<Task>>(...) {    
// HttpResponse<Task> is a type of the payload returned from my rest server
// 'it' is of type HttpResponse<Task>
}

现在,由于来自服务器的每个响应都将包装在 HttpResponse 中,我希望能够省略它声明方法调用的泛型类型,但仍然在回调中返回它

HttpClient.get<Task>(...) { /* 'it' is still of type HttpResponse<Type>*/ }

但问题是,当我将 HttpClient 更改为(注意杰克逊 readValue 和回调参数类型的更改类型)时:

inline fun <reified T> execute(path: String,
                               requestMethodString: HttpMethod,
                               data: String?,
                               callback: (response: HttpResponse<T>) -> Unit) {
    (...)
    callback(mapper.readValue(json.toString())) 
    //jackson using kotlin module reads type from what callback wants as 
    //callback(mapper.readValue<HttpResponse<T>>(json.toString())) 
    (...)
}

Jackson 不再能够反序列化我的有效负载,因为它不再知道类型,并且无法反序列化任何 T,当 T 表示从服务器返回的整个有效负载时,它会在我的原始示例中正常反序列化。

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to **.********.model.Task

我的问题是是否有人知道如何使它工作?问题出在 kotlin、jackson 还是我这边?由于具体的泛型类型,我可以以某种方式构建类型引用来组合我在运行时知道的两种类型吗?

val argumentClass = T::class.java
val containerClass = HttpResponse::class.java
val combinedType = ???
mapper.readValue(json.toString(), combinedType)

'get' 方法也只是用正确的 HttpMethod 调用 'execute' 方法,因为我之前没有显示,所以它不相关(我在更改为 HttpResponse 回调时也更改了类型)

标签: genericskotlinjacksonkotlin-reified-type-parameters

解决方案


推荐阅读