Android 从Java到Kotlin的代码转换后出现异常:Java.lang.ClassCastException:Java.lang.String无法转换为com.example.misc.Restaurant

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

我正在将我的应用程序从Java转换为Kotlin,在执行下面的代码时,我得到一个ClassCastException。想法

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)
        }

    }