Using the Kotlin standard library from Java

Danny Preussler
Google Developer Experts
4 min readJun 14, 2021

--

giphy.com

If you work with Kotlin on a daily basis you probably love the language and don’t want to go back to Java. Though, many of us work on a codebase that isn’t purely Kotlin. Our Android codebase at SoundCloud still has a fair amount of code written in Java. This percentage gets smaller over time but there is no urgent need for mass migration of the remains right now.

Therefore, every once in a while, I find myself, changing Java files. In those cases, I miss some of the Kotlin functions I’m used to; I can easily think of string manipulation or handling collections as examples. Of course, Java has powerful utility libraries such as Googles Guava or Apache Commons, libraries many of which we used to work with in the world before Kotlin.

But when writing Kotlin code all day, remembering those “older” APIs is sometimes hard. It is a complete context switch. It would be much easier to use what we use in Kotlin. And you should! Let me show you!

Let’s assume we want to create a list of items. In Kotlin, we would write:

val items = listOf(
items1, item2, item3
)

In Java, I would write it as:

List<Item> items = Arrays.asList(item1, item2, items3);

Usage is pretty much the same but you still need to remember the name of the function. Wouldn’t it be easier to just use:

List<Item> items = listOf(item1, item2, items3);

And yes you can!

All you need to do is to static importthat function! This works aslistOf, like many of our daily Kotlin utility functions, are simply static functions you can use from Java.

And even better, as your project already uses Kotlin, you already got those dependencies included anyway, no additional library needed.

A closer look

If you would click on the details of listOf from Kotlin, you would end up in a file called Collections.kt and the definition looks like this:

public fun <T> listOf(vararg elements: T): List<T>

It is a free function, not bound to any class. But from a Java perspective this looks something like this:

public final class CollectionsKt {
@NotNull
public static final List<T> listOf(@NotNull T... elements) {
...
}

Where does this class come from? Note that a function not bound to a class from Kotlin still has to be put into a class in bytecode. In this case, the functions from the file Collections.kt will simply end up in a class called CollectionsKt.
And in doubt, if you want to know the class name you need to static import in Java, simply go to the declaration of your Kotlin function and check the file name.

Extension function

What about extension functions? In my opinion, those are one of the most powerful tools Kotlin offers. From a Java point of view, extension functions are also just static functions where the receiver becomes the first argument. Let‘s look at an example:

validItems = items.filterNotNull()

filterNotNull is an extension function, as we can see in the declaration:

public fun <T : Any> Iterable<T?>.filterNotNull(): List<T>

From Java this looks something like this:

public static final List<T> filterNotNull(@NotNull Iterable<T> $this$filterNotNull)

The usage would look like this:

validItems = filterNotNull(items);

That’s not too bad, is it?

The only drawback when using extension functions from Java is that you can’t concatenate calls with other extension functions like you would do in Kotlin:

items.filterNotNull().find{...}.map{...}

This won’t work in Java, as we learned: the receiver becomes the first argument, so we would need to rewrite this to multiple lines of code. But each of the functions can be used though.

Side note

If you would look further into this example, you might notice that thefilterNotNull function sits in a file called _Collections.kt not Collections.kt. Still, we import the class CollectionsKt , the same name as we used to above. This is as the authors defined the target class name explicit via an annotation: @file:kotlin.jvm.JvmName(“CollectionsKt”)

Costs

You might ask if there are any hidden costs when using these Kotlin libraries from Java. The answer is simple: no! Kotlin libraries come in byte code like every library written in Java. The only thing you probably won't find in a normal Java library would be the null checks. Similar to when moving to Kotlin, be aware of sudden exceptions when passing null where it was not expected.

Summary

Many functions in Kotlin are implemented as extension functions and can easily be used from Java via static imports. You might not be able to use all of Kotlin's power, especially thinking of functionalities like Coroutines. Calling standard functions is not a problem though and should be used more often. And you might even get rid of some third-party libraries only used for Java.

Using the same function reduces the cognitive load for the team when working on mixed codebases. This is even more valuable with developers starting directly with Kotlin without having a long Java background which we will see more and more.

But let me remind you that this tip is for that intermediate state when your codebase is not fully Kotlin yet. If you have a Java project and planning with Java long term, using Kotlin libraries should not be your strategy.

--

--

Danny Preussler
Google Developer Experts

Android @ Soundcloud, Google Developer Expert, Goth, Geek, writing about the daily crazy things in developer life with #Android and #Kotlin