Reified: made (something abstract) more concrete or real. This keyword in Kotlin makes Kotlin a much better language for Android development. There’re 3 distinct nice bits as below.

No more passing clazz

This is most obvious and probably shared by many other post you have seen describing Reified usage. For completion, I’ll put this here as well.

Imagine if you like to have a common function that start an activity, you’ll have to have a parameter that pass in as Class<T> .

// Function

private fun <T : Activity> Activity.startActivity(

context: Context, clazz: Class<T>) {

startActivity(Intent(context, clazz))

} // Caller

startActivity(context, NewActivity::class.java)

The reified approach

With reified , this could be simplified to just the generic type.

// Function

inline fun <reified T : Activity> Activity.startActivity(

context: Context) {

startActivity(Intent(context, T::class.java))

} // Caller

startActivity<NewActivity>(context)

Safe unknown casting

In Kotlin, we know we have as? which will cast to the specific type and return a null if the cast is unsuccessful.

We think we could write the below function that safely get the data or return null…

// Function

fun <T> Bundle.getDataOrNull(): T? {

return getSerializable(DATA_KEY) as? T

} // Caller

val bundle: Bundle? = Bundle()

bundle?.putSerializable(DATA_KEY, "Testing")

val strData: String? = bundle?.getDataOrNull()

val intData: Int? = bundle?.getDataOrNull() // Crash

However, this function would crash 💥 if the data obtained is not of the type it is expecting.

Hence to safely get the data,

// Function

fun <T> Bundle.getDataOrNull(clazz: Class<T>): T? {

val data = getSerializable(DATA_KEY)

return if (clazz.isInstance(data)) {

data as T

} else {

null

}

} // Caller

val bundle: Bundle? = Bundle()

bundle?.putSerializable(DATA_KEY, "Testing")

val strData: String? = bundle?.getDataOrNull(String::class.java)

val intData: Int? = bundle?.getDataOrNull(String::class.java) //Null

This is not nice, not only on the way the function is written, but also the need to pass an extra clazz parameter

The reified approach

With reified , this could be simplified and use as? safely.

// Function

private inline fun <reified T> Bundle.getDataOrNull(): T? {

return getSerializable(DATA_KEY) as? T

} // Caller

val bundle: Bundle? = Bundle()

bundle?.putSerializable(DATA_KEY, "Testing")

val strData: String? = bundle?.getDataOrNull()

val intData: Int? = bundle?.getDataOrNull() // Null

Emulate different return type function overload

I want to have a function that calculate DP to Pixel, and return either an Int or a Float depending on the expected value.

Function overload came to my mind straight, as below.

fun Resources.dpToPx(value: Int): Float {

return TypedValue.applyDimension(

TypedValue.COMPLEX_UNIT_DIP,

value.toFloat(), displayMetrics)

} fun Resources.dpToPx(value: Int): Int {

val floatValue: Float = dpToPx(value)

return floatValue.toInt()

}

However, this will result in error at compile time. The reason is because, the Overload function signature can only differs by the argument count and type, and NOT the return type.

The reified approach

With reified , this could then be emulated