From functional Java to functioning Kotlin
Converting @FunctionalInterface to Kotlin
Java 8 introduced a new annotation called @FunctionalInterface
. It’s purpose is to be able to create an interface with one non-default method so that the interface can simulate functions being first class citizens in an Object Oriented language. For example, Comparable
is a @FunctionalInterface
with one method, compareTo(T o)
.
Callbacks are a really common case for functional interfaces. Imaging the following scenario where we want to perform some asynchronous work and return the results back to the client at a later time. In Java, we would have a class that looks like the following:
public class MyAwesomeAsyncService {
@FunctionalInterface
public interface AwesomeCallback {
void onResult(Result result);
} private final AwesomeCallback callback;
public MyAwesomeAsyncService(AwesomeCallback callback) {
this.callback = callback;
} public void doWork() {
...
callback.onResult(result);
}
}
We use a callback interface that has one method that the client code needs to implement.
While using the Kotlin converter in Android Studio, the converter did not optimize converting the @FunctionalInterface
.
class MyAwesomeAsyncService(private val callback: AwesomeCallback) {
@FunctionalInterface
interface AwesomeCallback {
fun onResult(result: Result)
} fun doWork() {
...
callback.onResult(result)
}
}
The converter created an interface for a one to one conversion, but could this be optimized further? In Kotlin there is a concept called SAM or Single Abstract Method. This is exactly what a @FunctionalInterface
is in Java 8 but the section in the docs to not have an example of how to create a SAM, only how to use a SAM.
After converting the interface into a function in the constructor, the boilerplate code around the @FunctionalInterface
shank from 96 characters to 38 characters. That’s a reduction of 40%!
class MyAwesomeAsyncService(private val onResult: (Result) -> Unit) {
fun doWork() {
...
onResult(result)
}
}
When examining the before and after, you can see how the code melts away into syntactic sugar with Kotlin.
If you are converting a project or writing in Kotlin, I would love to hear about what you stumbled upon and learned. If you would like to continue the discussion, leave a comment or talk to me on Twitter.