Kotlin усовершенствованный тип generi c, смешанный с классом-оболочкой типа generi c - PullRequest
1 голос
/ 19 апреля 2020

Я пытаюсь создать простой HttpClient в Kotlin. Я работал с типами generi c, используя встроенные функции с типом reified generi c, например:

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, я хотел бы иметь возможность пропустить его при объявлении типа вызова метода generi c, но все равно вернуть его в обратном вызове

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

Но проблема в том, что когда я меняю свой HttpClient на (обратите внимание на измененный тип для jackson 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())) 
    (...)
}

Джексон больше не может десериализовать мою полезную нагрузку, так как он не знает тип и больше не удается десериализовать любой T, который он обычно десериализовал бы в моем исходном примере, когда T представлял всю полезную нагрузку, возвращаемую с сервера.

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

Мой вопрос: знает ли кто-нибудь, как заставить это работать? Проблема на kotlin, Джексон или на моей стороне? Могу ли я как-нибудь создать ссылку на тип, чтобы объединить оба типа, которые я знаю во время выполнения, благодаря усовершенствованному типу generi c?

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

Также метод 'get' просто вызывает метод 'execute' с правильным HttpMethod, как я и не делал. не показывать, что раньше, так что это не имеет значения (я также меняю типы при переходе на обратный вызов HttpResponse)

...