Skip to content

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.

Advertisements

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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.