Здесь происходит несколько вещей.
Во-первых, традиционный способ передать тип - это передать его KClass
объект (используя ::type
) или Class
object (используя ::type.class
).
Таким образом, вы можете объявить свою функцию как:
fun convert(t: Class<*>): Any
Но это создает новую проблему: Gson().fromJson()
возвращает объектуказанного вами типа. В этом случае это может быть что угодно (отсюда *
), и поэтому компилятор не знает, можно ли на нем вызвать toList()
.
Одним из решений этого было бы дать типbound, например:
fun <T: Collection<U>, U> convert(t: Class<T>): List<U>
Это указывает, что тип, который вы передаете, должен быть некоторой реализацией Collection
, и что он возвращает List
с тем же типом элемента. И поскольку Collection
имеет метод toList()
, он все работает.
Однако это не сработает для вашего случая передачи типа Array
, так как массивы не имеют toList()
метод. (Array
типы немного неудобны в Kotlin. Они в основном для обратной совместимости с Java; List
s лучше во многих отношениях.)
Вы можете использовать вышеупомянутое, и использовать Listвведите напрямую. Однако вы не сможете указать тип элемента List:
fun <T: Collection<U>, U> convert(t: Class<T>): List<U> {
return Gson().fromJson(mockedResponse, t).toList()
}
val model: List<*> = convert(List::class.java)
Так что, вероятно, лучше оставить toList()
в вашей функции и вообще не ограничивать тип. Таким образом, вызывающая сторона может выполнить любое необходимое преобразование, которое сохранит тип элемента:
fun <T> convert(t: Class<T>): T {
return Gson().fromJson(mockedResponse, t)
}
val model: List<MyDataModel> = convert(Array<MyDataModel>::class.java).toList()
И в качестве окончательной настройки мы можем использовать другой, немного более аккуратный, способ передачи типов Котлина: сделать их реализованными. Эта замена выполняется во время компиляции, а не во время выполнения, и работает только для inline
функций:
inline fun <reified T> convert(): T {
return Gson().fromJson(mockedResponse, T::class.java)
}
val model: List<MyDataModel> = convert<Array<MyDataModel>>().toList()