Kotlin - Общий тип безопасен, неправильное предупреждение?java.lang.ClassCastException - PullRequest
0 голосов
/ 14 марта 2019

Я получаю ответ от какого-то API , после получения ответа я преобразовываю его в Список необходимых мне Object например:

fun <T> getAsList(input: String): ArrayList<T> {
    val objType = object : TypeToken<ArrayList<T>>() {}.type
    val result = Gson().fromJson(input, objType) as ArrayList<T>
    println(result[0]) // <-- no warning here !! It's work
    println("result: " + result.toString()) // Also it's work here
    return result
}

Затем я передаю этот список куда-нибудь, например:

updateFromDownload(getAsList<T>(resultValue))

И переопределив этот метод, я могу получить результат, например:

override fun updateFromDownload(result: List<Response>?) {

                val listTest = ArrayList<Response>()
                listTest.add(result!![0]) // <-- This work
                println(listTest)


                println("resss:"  + result[0]) // <-- This not work !!!
                for (response in result){
                    // The loop crash too, not work
                }

Как показано выше, добавление к listTest работает нормально, но если я попытался получить элемент по отдельности, как в getAsList() Это сбой из-за:

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap нельзя привести к ...... Ответ

Могу ли я получить доступ к result напрямую, не заполняя его новым списком?

Правка - весь цикл для кода:

class ConnectToURL<T>(callback: DownloadCallback<T>) : AsyncTask<String, Int, ConnectToURL.Result>() {

private var mCallback: DownloadCallback<T>? = null

init {
    setCallback(callback)
}

override fun onPostExecute(result: Result?) {
    mCallback?.apply {
        result?.mException?.also { exception ->
            //val gson = Gson().fromJson(result.mResultValue!!, type)
            //updateFromDownload(gson)
            return
        }
        result?.mResultValue?.also { resultValue ->
            updateFromDownload(getAsList<T>(resultValue))
            return
        }
        finishDownloading()
        }
    }

}

И я призываю ConnectToURL от:

 class BuilderClass<T> private constructor(
    callback: DownloadCallback<T>,
    private val url: String
) {

    init {
        ConnectToURL(callback).execute(url)
    }

    /// some code . . .. .

        fun build() = BuilderClass(callback, url)
    }
}

Затем я переопределяю функцию updateFromDownload, поскольку она является частью DownloadCallback

1 Ответ

0 голосов
/ 14 марта 2019

Универсальный тип T стирается во время компиляции, поэтому информация о типе отсутствует во время выполнения.

object : TypeToken<ArrayList<T>>() {}.type

По этой причине Gson не конвертируется в класс Response. Вы можете использовать inline плюс reified, чтобы избежать стирания типа.

inline fun <reified T> getAsList(input: String): ArrayList<T>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...