Something you may have missed about @JvmName
Kotlin is all the rage these days and rightfully so. Even though it’s been around for several years, it’s only since Google’s official support announcement that a lot of us are slowly migrating code to Kotlin.
There are a lot of good articles around how one should migrate their code to Kotlin and where to begin. Among those articles, one advice comes back quite often : “Start with your utility classes”. To be honest, that’s quite a good advice. Utility classes are often very focused and therefore contains very little code and specially have no side effects (or at least should have). Nevertheless, when starting to migrate code from utility classes, we encounter one side effects that might be problematic.
Before going further, let me illustrate with a little example. Let’s say we have an utility class that returns Android’s system services. The class would look like this :
We can easily use the action “Convert Java File to Kotlin File” to transform the java code to this :
Of course, this is not really idiomatic and we can refactor the class to this :
Since have declared those methods outside of a class, Kotlin will create a class in which it will put the static methods it will generate in byte code. By default, that class’ name will be composed of the file’s name and the suffix “Kt”. If you try to call this method from some Java code, the code will look like this :
And this is where this might become a problem for you.
First, you will have to change everywhere in your code where you used to call
ContextUtils to call
Then, and this is where I was more annoyed, you will expose to your Java code that this class is a Kotlin class.
To be fair, this might not be a problem for you. Maybe you have decided to move all your Kotlin classes to a
kotlin source folder (instead of using the default
java one) and you want to make it obvious that class is in that folder.
That isn’t my case and I don’t want to expose the nature of my classes in the Java code. Luckily, the amazing team at JetBrains thought of this and provided us with an annotation :
@JvmName. It is actually possible to annotate the file so that the generated class will use whatever name you want.
To do so, you need to add
@file:JvmName("ContextUtils") above the
package declaration. The code will now look like this :
And it’s now possible to call our class in Java without any indication of its nature :
I know this is not a ground breaking revelation. Also, if you have read the “Calling Kotlin from Java” Kotlin documentation page, it’s one of the first thing they mention.
Nevertheless, coming from the documentation of
@JvmName the link will bring you further down the page and you might miss it.
Hopefully, this article will have brought this nice feature to your attention and help you have a cleaner code.