Kotlin - 通用类型安全,错误警告? java.lang.ClassCastException

问题描述 投票:0回答:1

我从某些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的一部分

android generics kotlin
1个回答
0
投票

通用类型T在编译时被擦除,因此类型信息在运行时不存在。

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

这就是Gson没有转换为Response类的原因。您可以使用inline加上reified来避免类型擦除。

inline fun <reified T> getAsList(input: String): ArrayList<T>
© www.soinside.com 2019 - 2024. All rights reserved.