关于泛型导致 ClassCastException LinkedTreeMap cannot be cast to Any
About generics causing ClassCastException LinkedTreeMap cannot be cast to Any
Kotlin 代码
class ResponseBody<T> {
var code : Int = 0
var msg : String = ""
var data : T? = null
}
class ExampleT {
var text: String = ""
// var list: List<String>? = null
}
// utils fun
fun <T> request(json : String) : ResponseBody<T>? {
val gson = Gson()
var responseBody: ResponseBody<T>? = null
if (json.contains("code") && json.contains("data")) {
responseBody = gson.fromJson(json, object : TypeToken<ResponseBody<T>>() {}.type)
} else {
val tdata : T = gson.fromJson(json, object : TypeToken<T>() {}.type)
responseBody = ResponseBody()
responseBody.code = 200
responseBody.msg = "success"
responseBody.data = tdata
}
return responseBody
}
// main
val json : String = "{\"code\":200,\"msg\":\"success\",\"data\":{\"text\":\"text text text\"}}"
// val json : String = "{\"text\":\"text text text\"}"
val responseBody : ResponseBody<ExampleT> = request(json)
结果错误
ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to ExampleT
如何修改我的代码来解决这个问题?
从问题评论部分的 OP 回复来看,使用 reified
有助于解决问题。必须修改原始源代码才能使用 reified
关键字。内联函数并实现 Gson 的扩展函数以避免使用 TypeToken
class.
这是很棒的答案:
class ResponseBody<T> {
var code : Int = 0
var msg : String = ""
var data : T? = null
}
class ExampleT {
var text: String = ""
// var list: List<String>? = null
}
// utils fun
inline fun <reified T> request(json : String) : ResponseBody<T> {
val gson = Gson()
var responseBody: ResponseBody<T>? = null
if (json.contains("code") && json.contains("data")) {
return gson.fromJson(json)
} else {
val tdata : T = gson.fromJson(json)
responseBody = ResponseBody()
responseBody.code = 200
responseBody.msg = "success"
responseBody.data = tdata
}
return responseBody
}
inline fun <reified T> Gson.fromJson(json: String): T {
return fromJson(json, T::class.java)
}
// main
val json : String = "{\"code\":200,\"msg\":\"success\",\"data\":{\"text\":\"text text text\"}}"
// val json : String = "{\"text\":\"text text text\"}"
val responseBody : ResponseBody<ExampleT> = request(json)
Kotlin 代码
class ResponseBody<T> {
var code : Int = 0
var msg : String = ""
var data : T? = null
}
class ExampleT {
var text: String = ""
// var list: List<String>? = null
}
// utils fun
fun <T> request(json : String) : ResponseBody<T>? {
val gson = Gson()
var responseBody: ResponseBody<T>? = null
if (json.contains("code") && json.contains("data")) {
responseBody = gson.fromJson(json, object : TypeToken<ResponseBody<T>>() {}.type)
} else {
val tdata : T = gson.fromJson(json, object : TypeToken<T>() {}.type)
responseBody = ResponseBody()
responseBody.code = 200
responseBody.msg = "success"
responseBody.data = tdata
}
return responseBody
}
// main
val json : String = "{\"code\":200,\"msg\":\"success\",\"data\":{\"text\":\"text text text\"}}"
// val json : String = "{\"text\":\"text text text\"}"
val responseBody : ResponseBody<ExampleT> = request(json)
结果错误
ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to ExampleT
如何修改我的代码来解决这个问题?
从问题评论部分的 OP 回复来看,使用 reified
有助于解决问题。必须修改原始源代码才能使用 reified
关键字。内联函数并实现 Gson 的扩展函数以避免使用 TypeToken
class.
这是很棒的答案:
class ResponseBody<T> {
var code : Int = 0
var msg : String = ""
var data : T? = null
}
class ExampleT {
var text: String = ""
// var list: List<String>? = null
}
// utils fun
inline fun <reified T> request(json : String) : ResponseBody<T> {
val gson = Gson()
var responseBody: ResponseBody<T>? = null
if (json.contains("code") && json.contains("data")) {
return gson.fromJson(json)
} else {
val tdata : T = gson.fromJson(json)
responseBody = ResponseBody()
responseBody.code = 200
responseBody.msg = "success"
responseBody.data = tdata
}
return responseBody
}
inline fun <reified T> Gson.fromJson(json: String): T {
return fromJson(json, T::class.java)
}
// main
val json : String = "{\"code\":200,\"msg\":\"success\",\"data\":{\"text\":\"text text text\"}}"
// val json : String = "{\"text\":\"text text text\"}"
val responseBody : ResponseBody<ExampleT> = request(json)