Lambda as argument is different when calling Java and Kotlin


#1

If I have this java class

public class JavaClass {
public void withAction(Runnable action) {
}
}

Then I can call it from Kotlin like this:
JavaClass().withAction { println(“Hello”) }

But when I have this kotlin class:

class KotlinClass {
fun withAction(action: Runnable) {}
}

Then I have to call the method like this:

KotlinClass().withAction(Runnable { println(“Hello”) })

I can not call it like:

KotlinClass().withAction { println(“Hello”) }

Why is that? Why do I have to say its a Runnable when calling kotlin code but not when calling java code?
Please note that I do not want to change my kotlin class


#2

As the language currently is silent SAM conversion is only supported when calling methods defined outside of Kotlin (read Java). Kotlin supports function types where Java fudges it by allowing a SAM class to work as function type. Silent SAM conversion makes mistakes in that regard quite easy, but when classes are written in Java it is too much noise. Kotlin classes are expected to take function types (note that the function types are SAM compatible for Java use - they are just generically named).