fun main(args: Array<String>) {
runnable.run()
runnable2.run()
val runnable: Runnable = Runnable {
//println(this) // does not compile
val runnable2: Runnable = object : Runnable {
override fun run() {
println(this)
I don’t know the original consideration behind this, but it makes sense to me: If you want to use the ‘SAM function literal’, which is more a functional programming style, ‘this’ pointer is kind of confusing.
So by forcing you to use the ‘object : Class’ anonymous class syntax, you will know it’s more a traditional class, where ‘this’ makes more sense.
this
in a lambda refers to the instance of the containing class, if any. A lambda is conceptually a function, not a class, so there is no such thing as a lambda instance to which this
could refer.
The fact that a lambda can be converted into an instance of a SAM interface does not change this. Having this
in a lambda mean different things depending on whether the lambda gets SAM-converted would be extremely confusing.
I understand that a SAM lambda doesn’t really fit any of the rules documented at https://kotlinlang.org/docs/reference/this-expressions.html and would required a special case. I was just surprised that there was no reference to the instance being created from within itself.
It is also impossible to make them recursive or queue themselves with a Handler.
By the way, while “this” does not work in a SAM, it does work in your original code:
val handler = Handler()
val runnableCode = object : Runnable {
override fun run() {
// do something
handler.postDelayed(this, 2000)
handler.post(runnableCode)
Here’s what I did to work around the same problem:
fun runnable(body: Runnable.(Runnable)->Unit) = object: Runnable {
override fun run() {
this.body(this)
Then you just change Runnable
to runnable
and everything works as you expect (and you can use this
):
val handler = Handler()
val runnableCode = runnable {
// do something
handler.postDelayed(this, 2000) // perfectly OK now
handler.post(runnableCode)
Since it’s an extension function you don’t need to pass this
as a parameter. I normally use this:
inline fun runnable(crossinline body: Runnable.() -> Unit) = object : Runnable {
override fun run() = this.body()
But why using lambdas when you need a reference to the code block itself ? That’s what functions are about : naming a set of instructions so you can easily refer to it.
In my point of view, using lambdas for such intricated cases is harmful. You don’t properly separate concerns, and prevent proper signature/documentation.
In Java FX, there is a scene: void addListener(ChangeListener<? super T> listener);
by SAM.
If I can get the ref of ChangeListener
that I can use removeListener(Listener)
.
Maybe it is more …pretty?