Android 从Java到Kotlin的代码转换后出现异常:Java.lang.ClassCastException:Java.lang.String无法转换为com.example.misc.Restaurant
我正在将我的应用程序从Java转换为Kotlin,在执行下面的代码时,我得到一个ClassCastException。想法Android 从Java到Kotlin的代码转换后出现异常:Java.lang.ClassCastException:Java.lang.String无法转换为com.example.misc.Restaurant,android,kotlin,Android,Kotlin,我正在将我的应用程序从Java转换为Kotlin,在执行下面的代码时,我得到一个ClassCastException。想法 private fun getImageFragments(imagesList: MutableList<Restaurant?>?) { if (imagesList != null) { val restaurant: Restaurant? = imagesList[0] /*exception: java.lang.ClassCast
private fun getImageFragments(imagesList: MutableList<Restaurant?>?) {
if (imagesList != null) {
val restaurant: Restaurant? = imagesList[0]
/*exception: java.lang.ClassCastException:
java.lang.String cannot be cast to com.example.misc.Restaurant */
}
}
此外,当我试图将有问题的行重写为
val restaurant: String? = imagesList[0]
我得到:
Type mismatch: inferred type is Restaurant? but String? was expected
编辑:
因此,根据请求,我将发布更多的代码,但请注意,这不会很好。相信我,如果它没有关闭,我会很乐意向你展示整个过程,但主要原因是我不想让你受苦。问你是否想要更多。以下是调用getImageFragments的函数的代码:
getDrawerBanners(App.preference.getString("language", "ENG"),
object : OnAPIRequestListResultListener<Restaurant?> {
override fun onListResult(list: MutableList<Restaurant?>?) {
bannerViewPager.adapter = fragmentManager?.
let{ DrawerBannersAdapter(it, getImageFragments(list)) }
}
})
getDrawerBanners(App.preference.getString(“语言”、“英语”),
对象:OnAPIRequestListResultListener{
覆盖fun onListResult(列表:可变列表?){
bannerviewpage.adapter=fragmentManager?。
让{DrawerBannersAdapter(it,getImageFragments(list))}
}
})
这是一个PirRequestListResultListener接口,我有一种强烈的感觉,错误可能隐藏在这里的任何地方,如果您认为不是这样,请继续阅读
interface OnAPIRequestListResultListener<T> {
fun onListResult(list: MutableList<T>?)
}
PireRequestListResultListener上的接口{
有趣的onListResult(列表:可变列表?)
}
原始签名+GetDroperBanners函数体
// Downloading banners from server
@JvmStatic
fun getDrawerBanners(languageCode: String?, listener:
OnAPIRequestListResultListener<Restaurant?>) {
val async = GetMenuBannersAsync(listener)
async.execute(languageCode)
}
//从服务器下载横幅
@JvmStatic
有趣的GetDrawerBanner(语言代码:String?,侦听器:
OnAPIRequestListResultListener){
val async=GetMenuBannersAsync(侦听器)
执行(语言代码)
}
GetMenuBannersAsync
private class GetMenuBannersAsync(var listener:
OnAPIRequestListResultListener<Restaurant?>) : AsyncTask<String?, Void?, Void?>() {
var bannersUrls: MutableList<Restaurant?> = ArrayList()
override fun doInBackground(vararg params: String?): Void? {
val url = "https://api.smartapp.com/App/Language/" + params[0]
val client: HttpClient = DefaultHttpClient()
val httpGet = HttpGet(url)
httpGet.addHeader(AUTHORIZATION, AUTHORIZATION_STRING)
var httpResponse: HttpResponse? = null
var httpEntity: HttpEntity? = null
httpResponse = client.execute(httpGet)
httpEntity = httpResponse.entity
val response = EntityUtils.toString(httpEntity)
val json = JSONObject(response)
// Getting drawer banner
val bannersArray = json.getJSONArray("mainMenuBanners")
bannersUrls = ArrayList()
for (i in 0 until bannersArray.length()) {
val bannerObj = bannersArray.getJSONObject(i)
val imageUrl = bannerObj.getString("image")
(bannersUrls as ArrayList<String>).add(imageUrl)
}
return null
}
override fun onPostExecute(result: Void?) {
listener.onListResult(bannersUrls)
super.onPostExecute(result)
}
}
私有类GetMenuBannersAsync(变量侦听器:
OnAPIRequestListResultListener):异步任务(){
var bannersUrls:MutableList=ArrayList()
重写fun doInBackground(vararg参数:String?):Void{
val url=”https://api.smartapp.com/App/Language/“+params[0]
val client:HttpClient=DefaultHttpClient()
val httpGet=httpGet(url)
httpGet.addHeader(授权,授权字符串)
var httpResponse:httpResponse?=null
var httpEntity:httpEntity?=null
httpResponse=client.execute(httpGet)
httpEntity=httpResponse.entity
val响应=EntityUtils.toString(httpEntity)
val json=JSONObject(响应)
//获取抽屉横幅
val bannersArray=json.getJSONArray(“mainMenuBanners”)
bannersUrls=ArrayList()
for(在bannersArray.length()之前,输入0){
val bannerObj=bannerArray.getJSONObject(i)
val imageUrl=bannerObj.getString(“图像”)
(作为ArrayList的横幅URL)。添加(imageUrl)
}
返回空
}
重写onPostExecute(结果:Void?){
listener.onListResult(横幅URL)
super.onPostExecute(结果)
}
}
问题在于您的getmenubanersasync
函数。在这里,您可以创建类型为MutableList
的bannersUrls
列表,但您可以使用将值放入列表中(bannersUrls作为ArrayList)。添加(imageUrl)
。cast表达式告诉编译器您所做的转换是save,而在您的示例中不是这样
因此,请始终记住,如果您使用强制转换,类型系统将不再帮助您检测问题,那么您只能依靠自己。您需要确保转换是安全的
要解决实际问题,您需要创建餐厅对象并将其放入列表中,而不是URL。问题在于您的
GetMenuBannersAsync
函数。在这里,您可以创建类型为MutableList
的bannersUrls
列表,但您可以使用将值放入列表中(bannersUrls作为ArrayList)。添加(imageUrl)
。cast表达式告诉编译器您所做的转换是save,而在您的示例中不是这样
因此,请始终记住,如果您使用强制转换,类型系统将不再帮助您检测问题,那么您只能依靠自己。您需要确保转换是安全的
要解决实际问题,您需要创建餐厅对象并将其放入列表中,而不是URL。列表中似乎包含字符串对象而不是餐厅。如果使用反射,或者例如使用引擎盖下反射的序列化库,则可能会发生这种情况。您是否使用调试器检查了列表的实际内容?在调用函数getImageFragments之前,显示您准备paremeter imageList的代码。当然这是一个错误,我已经复制了它。这可能是由于类型擦除,我将对此提出一个问题。@Jannik这确实是一个错误,您可以看到,在Java中,您不能将
列表
强制转换为列表
,因为它们是不变的。您可以阅读有关协方差、不变性和逆变换的更多信息。kotlin的声明已经表明,MutableList在默认情况下是不变的,这意味着MutableList
MutableList
之间没有关系,这就是强制转换不应该成功的原因。@AmonChepri的问题确实在那一行(作为ArrayList的横幅URL)。添加(imageUrl)
,你应该注意列表,不要放任何东西,除了餐厅?
,但正如我所说的,代码永远不应该被编译,因此它是一个bug。你的列表似乎包含一个字符串对象而不是餐厅。如果使用反射,或者例如使用引擎盖下反射的序列化库,则可能会发生这种情况。您是否已使用调试器检查了列表的实际内容?在调用函数getImageFragments之前,显示您准备paremeter imageList的代码。当然这是一个错误,我已复制了它。这可能是由于类型擦除,我将对此提出一个问题。@Jannik这确实是一个错误,您可以看到在Java中无法强制转换
private class GetMenuBannersAsync(var listener:
OnAPIRequestListResultListener<Restaurant?>) : AsyncTask<String?, Void?, Void?>() {
var bannersUrls: MutableList<Restaurant?> = ArrayList()
override fun doInBackground(vararg params: String?): Void? {
val url = "https://api.smartapp.com/App/Language/" + params[0]
val client: HttpClient = DefaultHttpClient()
val httpGet = HttpGet(url)
httpGet.addHeader(AUTHORIZATION, AUTHORIZATION_STRING)
var httpResponse: HttpResponse? = null
var httpEntity: HttpEntity? = null
httpResponse = client.execute(httpGet)
httpEntity = httpResponse.entity
val response = EntityUtils.toString(httpEntity)
val json = JSONObject(response)
// Getting drawer banner
val bannersArray = json.getJSONArray("mainMenuBanners")
bannersUrls = ArrayList()
for (i in 0 until bannersArray.length()) {
val bannerObj = bannersArray.getJSONObject(i)
val imageUrl = bannerObj.getString("image")
(bannersUrls as ArrayList<String>).add(imageUrl)
}
return null
}
override fun onPostExecute(result: Void?) {
listener.onListResult(bannersUrls)
super.onPostExecute(result)
}
}