简体   繁体   中英

How to pass Kotlin lambda to Java Supplier argument?

I migrate my project to Kotlin and this phase has a lot of interaction between Java and Kotlin.

In sample below I need to pass a function which implements Java Supplier interface.

java.util.concurrent.CompletableFuture.supplyAsync<Int>({ -> 3 }, executor)

CompletableFuture.supplyAsync({ 3 }, executor)

IntellJ shows error:

Type mismatch.
Required: Supplier<Int!>!
Found: () -> Int

I found a workaround with a helper class but it is not an inline solution.

class Help : Supplier<Int> { fun get() = 3 }
supplyAsync(Help(), executor)

This will work:

CompletableFuture.supplyAsync({ 3 }, executor::execute)

Note that the two signatures are

public static <U> supplyAsync(supplier: Supplier<U>, executor: Executor): CompletableFuture<U>
public static <U> supplyAsync(supplier: () -> U, executor: (Runnable) -> Unit): CompletableFuture<U>

That is, if you want to pass in a lambda, the thing that executes it has to be a method reference (instead of an Executor instance).

Edit: This is documented here , Kotlin allows you to call methods that take SAM (functional interface) parameters with proper Kotlin functions as arguments. However, this is all or nothing. Either you pass a Kotlin function for all SAM parameters, or for none. This explains why the approach you originally took didn't compile. This is not specific methods of the Java API, but instead works for all methods defined on Java classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM