I am in a process of converting my app from Java to Kotlin and I am getting a ClassCastException while executing the code below. Thoughts?
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 */
}
}
Not sure if the implementation of the Restaurant Class is of any importance in this case? https://pastebin.com/q5z76exh
While inspecting the contents of imagesList[0] with debugger I am seeing this:
ArrayList size = 1
https://domainName.com/files/app/banners/1550449003515.png
count=116
hash:0
shadow$_klass_=class java.lang.String
shadow$_monitor_
Moreover, when I try to rewrite the problematic line to
val restaurant: String? = imagesList[0]
I am getting:
Type mismatch: inferred type is Restaurant? but String? was expected
EDIT:
So as per requests I am posting some more code, be warned though, it's not going to be pretty. Trust me, I would gladly show you the whole thing if it wasn't closed but the main reason is I don't want you to suffer. Ask if you want more. Here is the code of the function that is calling getImageFragments:
getDrawerBanners(App.preference.getString("language", "ENG"),
object : OnAPIRequestListResultListener<Restaurant?> {
override fun onListResult(list: MutableList<Restaurant?>?) {
bannerViewPager.adapter = fragmentManager?.
let{ DrawerBannersAdapter(it, getImageFragments(list)) }
}
})
And here is OnAPIRequestListResultListener interface, I have a strong feeling that error might be hidden smowewhere here, if you think otherwise read on further.
interface OnAPIRequestListResultListener<T> {
fun onListResult(list: MutableList<T>?)
}
Original signature + body of getDrawerBanners function
// Downloading banners from server
@JvmStatic
fun getDrawerBanners(languageCode: String?, listener:
OnAPIRequestListResultListener<Restaurant?>) {
val async = GetMenuBannersAsync(listener)
async.execute(languageCode)
}
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)
}
}
List<Integer>toList<Object>because they are invariant imgur.com/a/PV0KWKQ You can read more about covariance, invariance and contravariance here. The KDoc of kotlin already suggests that MutableList is invariant by default that means there is no relation betweenMutableList<Int>MutableList<Any>, that's why the cast shouldn't be successful.(bannersUrls as ArrayList<String>).add(imageUrl), you should take care of the list and never put anything else thanRestaurant?but as I said that code should never be compiled hence it is a bug.