So I've been playing around with Lambdas and Functions, and the difference between the two in kotlin and Java.
And I get confused as to where Supplier(function) comes from. Is it a constructor? Is it an extention function in Kotlin? WHat is it.
@Test
fun testLambdasAndFunctions() {
val stringFunction: () -> String = {"this is a string"}
val stringSupplier: Supplier<String> = Supplier { "this is another string" }
val anotherStringSupplier: Supplier<String> = Supplier(stringFunction)
assertThat(stringFunction()).isEqualTo("this is a string")
assertThat(stringSupplier.get()).isEqualTo("this is another string");
assertThat(stringFunction.toString()).isEqualTo("Function0<java.lang.String>");
assertThat(stringSupplier.toString()).isEqualTo("Function0<java.lang.String>");
}
CodePudding user response:
Supplier is a functional interface*.
Kotlin provides psuedo-constructors for functional interfaces as a language feature. Interfaces don't have actual constructors since they are not classes.
The psuedo-constructor is an inline function with the name of the interface that takes a single argument of a functional type matching the signature of the functional interface's single abstract method (SAM).
The function you are calling is not visible in any source code (since it's just syntactic sugar), but it would look like this:
inline fun <T> Supplier(crossinline block: ()->T): Supplier<T> =
object: Supplier<T> {
override fun <T> get(): T = block()
}
Because of Kotlin's trailing lambda syntax, you can use the Supplier { }
syntax to call this psuedo-constructor to create an instance.
The equivalent Java code you're creating is an anonymous object and would look like:
new Supplier<String>() {
public String get() {
//...
}
}
*A functional interface is an interface that has a single abstract method. If the interface is defined in Kotlin, it must also have the fun
keyword in front of interface
for it to be considered a functional interface.
CodePudding user response:
This is Kotlin's SAM conversion mechanism.
When you have a functional interface (an interface with a Single Abstract Method, a.k.a SAM), Kotlin can automatically convert a lambda that matches the signature of that SAM into an instance of that interface. It also generates a function with the name of the interface that takes a lambda as a parameter so you can write the conversion explicitly, which may be required in some cases.
This mechanism works both for Kotlin's functional interface (fun interface
) and for Java's functional interfaces (usually annotated @FunctionalInterface
). Supplier
is one such interface, hence why you have access to this mechanism here.