{{announcement.body}}
{{announcement.title}}

Calling Java Functional Interfaces from Kotlin

DZone 's Guide to

Calling Java Functional Interfaces from Kotlin

A brief demonstration of how to call functional interfaces from Kotlin using both single- and multi-use generics.

· Java Zone ·
Free Resource

Basics

Below is a Functional Interface defined in Java:

Java

Note, that an interface does not need to be annotated with @FunctionalInterface to be treated as one.

In Kotlin, this can be implemented with the following code:

Kotlin

As the Executor interface has only a single function, with a single input parameter, it can assign a type to the lambda passed to execute. This removes the need to define it explicitly as Runnable. This is known as SAM (Single Abstract Method) conversion, see the Kotlin docs for more information.

A more verbose way to achieve the same goal looks like:

Kotlin
 




xxxxxxxxxx
1


 
1
executor.execute(Runnable { println("I am a runnable") })


If you are using Intellij, it will kindly guide you to the first solution.

Single-Type Generics

Let’s make it a bit more exciting and include some generics this time round. Taking the Java interface and a function to call it:

Java

The doStuff function can be called with the following Kotlin code:

Kotlin
 




xxxxxxxxxx
1


 
1
// Least simplified
2
doStuff(MyJavaInterfaceWithGenerics<String> { "hi" })
3
// A bit more simplified
4
doStuff(MyJavaInterfaceWithGenerics { "hi" })
5
// Specify generic type explicitly
6
doStuff<String> { "hi" }
7
// Let Kotlin do the work
8
doStuff { "hi" }


The return type of the most simplified code is determined by the lambda’s result, which in this case is a String.

Multi-Type Generics

What about when the generics get a bit more complicated? I have spiced up the example code a bit to demonstrate this:

Java
 




xxxxxxxxxx
1


1
@FunctionalInterface
2
public interface MyJavaInterfaceWithGenerics<A, B, C> {
3
  C execute(A a, B b);
4
}
5
 
          
6
public static <A, B, C> C doStuff(A a, B b,  MyJavaInterfaceWithGenerics<A, B, C> myJavaInterface) {
7
  return myJavaInterface.execute(a, b);
8
}


I actually had a bit of trouble thinking of an example to demonstrate both input and output generics. I believe this code is pretty ugly and is unlikely to represent genuine code. Still, it should be good enough for an example.

To call this you would use the code below:

Kotlin
 




xxxxxxxxxx
1
11


 
1
// Least simplified
2
doStuff(1, 2L, MyJavaInterfaceWithGenerics<Int, Long, String> { a, b -> "hi" })
3
// Determine types from lambda instead of defining on the interface
4
doStuff(1, 2L, MyJavaInterfaceWithGenerics { a: Int, b: Long -> "hi" })
5
// Simplified some more
6
doStuff(1, 2L, { a, b -> "hi" })
7
// Fully simplified (extract lambda out of brackets)
8
doStuff(1, 2) { a, b -> "hi" }
9
// Determine type information from lambda (not all types had to be provided here)
10
// Removing the [Long] type will cause the compiler to choose an [Int] instead
11
doStuff(1, 2) { a, b: Long -> "hi" }


As I mentioned a second ago, realistically, the generic input types A and B in this example would be provided from an external source. Furthermore, the generic types would be specified on an overarching class or be locked down to specific types from the beginning.


If you enjoyed this post or found it helpful (or both) then please feel free to follow me on Twitter at @LankyDanDev and remember to share with anyone else who might find this useful!

Topics:
kotlin ,java ,functional interfaces ,single type generics ,multi type generics

Published at DZone with permission of Dan Newton , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}