Runnable vs () -> Unit

In Java, whenever you want to wrap some actions and execute them later, we will probably use Runnable implementation. The run() method of the Runnable interface takes in no parameters and returns nothing. Many methods will take in Runnable as a callback or as a way to execute actions later.

In Kotlin, the more idiomatic way is to use an anonymous function, i.e, a lambda expression. In this case the run() is () -> Unit. If you forgot the syntax, it has the same semantic as { print("Hello world") }

But not for their usages

Kotlin is designed to simplify code writing, they make it simpler by calling methods that take in a SAM (Single Abstract Method). For example, the Android Handler class has post() method, which requires a Runnable, so in Kotlin, you can simply write:

val handler = Handler()
handler.post {
Log.d(TAG, "action")
}﻿

Suppose now you want to remove the runnable, you may want to call the removeCallbacks() method, like this:

handler.removeCallbacks {
Log.d(TAG, "action")
}﻿

Well, this is NOT going to work. To remove callbacks, Handler actually compares the references of the Runnable objects, and only the same reference that we passed into the post() method will be removed. In this case, two lambda expressions actually create two different objects. Although their contents are exactly the same, the posted Runnable will still be run.

Take a look at the decompiled bytecode (as in Tools -> Kotlin -> Show Kotlin Bytecode):