Я хочу создать общий метод для преобразования строки json в список объектов.

fun  convertJsonStringToObjectList(jsonString: String , clazz: Class<Any>) :List<Any>{
        val gson = Gson()
        val objectList = gson.fromJson(jsonString, Array<clazz>::class.java).asList()
        return objectList
}

Этот код не работает. Я знаю, как преобразовать строку json в такой класс:

 fun <T> convertJsonStringToObject(jsonString: String, clazz: Class<T>): T {
        val gson = Gson()
        val objectList = gson.fromJson(jsonString, clazz)
        return objectList
    }

Проблема в том, что я хочу получить тип класса из метода, а затем добавить к нему тип массива и снова получить тип класса. Я не знаю, как с этим справиться.

0
Mahdi 7 Ноя 2019 в 08:53

1 ответ

Из-за стирания типов и специальных типов отражения массивов в jvm вы не можете сделать это действительно чистым, но есть способ использовать ключевое слово reified в kotlin, в котором это возможно:

inline fun <reified T> convertJsonStringToObject(jsonString: String): Array<T> =
    Gson().fromJson(jsonString, emptyArray<T>().javaClass)

(Вы можете заметить, что я использовал emptyArray<T> для получения типа вместо Array<T>::class.java. Поскольку последний даст вам Object[], а не Array<T>. Это может быть ошибка в котлине.)

(это может выглядеть уместно здесь, но недостаточно для сложных случаев, потому что мы сделали это inline.)

Кроме того, вот два альтернативных метода:

Передача типа массива в функцию (например, java):

fun <T> convertJsonStringToObject(
    jsonString: String, 
    clazz: Class<Array<T>>): Array<T> =
    Gson().fromJson(jsonString, clazz)

//and call it like this:
val result = convertJsonStringToObject(
    "[{\"test\":123}, {\"test\": 456}]", 
    Array<Test>::class.java)

Разбор массива json вручную один за другим:

fun <T> convertJsonStringToObjectList(
    jsonString: String, 
    clazz: Class<T>): List<T> {
    val gson = Gson()
    val objects = gson.fromJson(jsonString, JsonElement::class.java).asJsonArray
    return objects.map { gson.fromJson(it, clazz) }
}

(опять же, вы можете опустить параметр clazz, используя reified)

1
momvart 9 Ноя 2021 в 22:43