Safe casting in Kotlin
In multiple cases you might’ve came across the situation where you have to cast a global variable and check the instance beforehand.
A most common case in Android environment is to check whether the (hosting) activity implements a callback or extended from a specific one.
Before
if (activity is BaseActivity) { (activity as BaseActivity).hideKeyboard() }
After
Same can be written in sweet Kotlin syntax in a single line.
(activity as? BaseActivity)?.hideKeyboard()
Official documentation says Use the safe cast operator as? that returns null on failure.
How is this better?
In surface it might not look like a better code overhaul. As calls to activity increase in numbers, it gets better.
// CreateTweetFragment.kt fun submit() { // Fire and forget API call if (activity is BaseActivity) { (activity as BaseActivity).hideKeyboard() } if (activity is TweetSubmittedCallback) { (activity as TweetSubmittedCallback).onTweetSubmitted() } }
We could easily cast the activity to the exact subclass and invoke both methods.
// CreateTweetFragment.kt fun submit() { // Fire and forget API call if (activity is TwitterActivity) { (activity as TwitterActivity).hideKeyboard() (activity as TwitterActivity).onTweetSubmitted() } }
But it enforces the CreateTweetFragment to be attached to the TwitterActivity to execute both statements. Anything that is just a BaseActivity or TweetSubmittedCallback won’t execute the statement even though the implementation is in place.
Now with the as?
operator, both statements can be executed independent of each other.
fun submit() { // Fire and forget API call (activity as? BaseActivity)?.hideKeyboard() (activity as TweetSubmittedCallback)?.onTweetSubmitted() }