Home > Back-end >  How to use Kotlin parameter callback interoperable with a java class
How to use Kotlin parameter callback interoperable with a java class

Time:08-18

This question is about the parameter callback in Kotlin, which is by the way a very nice feature from my point of view!

I have a method written in Kotlin like this one which expects a callback as argument. The callback itself expects a String argument, which should be given to the callback invocation reciever:

 `private fun m1(number: Int, callback: (result: String) -> Unit) {
    //some other stuff..
    val string = "Foo"
    callback.invoke(string)
  }`

Then usually I would use it in Kotlin like this way:

m1(101) { processResult(it) } Whereas it the actual result is

BUT... how to get and process the callback result if the caller of the method is a Java class? I tried something like this one but it does not work:

`m1(101, () -> processResult(result));`

Thanks for any help! See you later.

CodePudding user response:

Here is how you need to call higher order function in java.

With Lambda:

m1(101, () -> {
processResult(result)
return null; //or return Unit.INSTANCE;
});

Without Lambda:

m1(101,new Function0<Unit>() {
            @Override
            public Unit invoke() {
                System.out.println("Hello");
                return null; //or return Unit.INSTANCE;
                
            }
        });

You can see the invoke function above. It returns Unit. Unit is similar to void in Java. Kotlin takes the default value. But in java you need to return Unit instance. You can return null or Unit.Instance . Both will be working as it would do nothing with the return value here. Here Function0 is an interface which takes zero argument in invoke method. Similary if you higher order function contains 1 argument, you need to use Function1 and so on.

CodePudding user response:

Thanks for your very quick responses.

I used the proposed syntax from @k314159 which was: m1(101, result -> processResult(result)); and it works. But then I need to return null or Unit.INSTANCE in my method m1()

I found out that in this case I can use in java also a method reference instead of a lambda as an argument:

m1(101, this::processResult);

The answer from @Gowtham solved my problem completely without changing code in my method. I did something like: m1(101, result -> { process(result); return null; /* or return Unit.INSTANCE */ });

And this made my day :)

  • Related