Cannot check for instance of erased type: List<Occupation_Info>

Viewed 1935

I am getting an error to fetch the list in function

fun insert(insert_info_list: List<Any>){
    viewModelScope.launch(Dispatchers.IO) {
        when(insert_info_list){
            is List<Occupation_Info> ->{
               insert_info_list.forEach {
                   var show_occupation_info=Occupation_Info(it.occupation_id,it.fn,it.fv)
                   db.daoOccupationInfo().insertOrUpdate(show_occupation_info)
               }
           }
        }
    }
}
2 Answers

This is because of type erasure.

To get around it, one option would be to move your type check inside the loop. This is not exactly equivalent to what you're trying to do above, so be careful. You might have a list of objects for which some objects implement multiple types.

In my code below, I removed your specifying of Dispatcher because it's unnecessary if you mark your DAO functions as suspend.

fun insert(insert_info_list: List<Any>){
    viewModelScope.launch {
        for (item in insert_info_list) {
            when(item) {
                is Occupation_Info -> {
                   var show_occupation_info = Occupation_Info(item.occupation_id, item.fn, item.fv)
                   db.daoOccupationInfo().insertOrUpdate(show_occupation_info)
                }
                // is...
            }
        }
    }
}

Or you can make the type of the input list reified so you can check it. The downside to this is the type of the list must be known to the compiler at the call site.

inline fun <reified T> insert(insert_info_list: List<T>){
    viewModelScope.launch {
        @Suppress("UNCHECKED_CAST")
        when (T::class) {
            Occupation_Info::class -> (for item in (insert_info_list as List<Occupation_Info>)) {
               var show_occupation_info = Occupation_Info(item.occupation_id, item.fn, item.fv)
               db.daoOccupationInfo().insertOrUpdate(show_occupation_info)
            }
            // SomethingElse::class...
        }
    }
}

Probably the best solution is to have separate insert functions for each type of list you want to support so you aren't having to do type checking, which is a code smell. If there is some common action you do to every type of list you process, you can break that common code out into a private function that each of your insert functions calls.

Kotlin ensures type safety for operations involving generics at compile time, while, at runtime, instances of generic types don't hold information about their actual type arguments. For example, List is erased to just List<*>. In general, there is no way to check whether an instance belongs to a generic type with certain type arguments at runtime.

Documentation you need

Related