Reputation: 113
I am using ViewModelFactory in my android app to pass some data to my ViewModel from Fragment. I'm getting unchecked cast warning. If I'm using Supress the warning goes away. I was wondering is there any way to handle this without using Supress("UNCHECKED_CAST")
The code I'm using to create the ViewModelFactory
val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
//factory to pass necessary data to ViewModel
@NonNull
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return activity?.application?.let {
BookReaderViewModel(
it,
"local",//todo:remote or local book. value will come from arguments
1//todo: bookId will come from arguments
)
} as T
}
}
as T is getting the warning.
Upvotes: 8
Views: 5642
Reputation: 6495
No, an unchecked cast means the compiler cannot guarantee a cast will fail or succeed.
In most cases there is nothing you can add to change that because the compiler simply does not have enough information. This usually happens around generis as T can represent many different types.
You have to add the correct type checks before casting so you are sure the cast succeeds.
You can suppress the warning. By doing that you, as a developer, promise the compiler that you are sure that the cast will always succeed.
The code as it is can't make that promise. If the create
function gets called with anything else than a BookReaderViewModel
it will crash because the cast doest not succeed.
Here's example where it's safe to suppress the warning because it checks before it casts:
@NonNull
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
val application = activity?.application ?: return null
if (modelClass == BookReaderViewModel::class.java) {
return BookReaderViewModel(
application,
"local",
1) as T
}
// return null or throw exception here
throw IllegalArguentException("Factory cannot make ViewModel of type ${modelClass.simpleName}")
}
Upvotes: 3