In Java, we can create an utilities class like this:
final class Utils {
public static boolean foo() {
return false;
}
}
But how to do this in Kotlin?
I try using functions inside object
:
object Utils {
fun foo(): Boolean {
return false
}
}
But when call this method from Java code it need to add INSTANCE
. Ex: Utils.INSTANCE.foo()
.
Then I change to declare it as top-level function (without class
or object
):
@file:JvmName("Utils")
@file:JvmMultifileClass
fun foo(): Boolean {
return true
}
Then I can call Utils.foo()
from Java code. But from Kotlin code I got Unresolved reference
compiler error. It only allow be to use foo()
function directly (without Utils
prefix).
So what is the best approach for declaring utils class in Kotlin?
The last solution you've proposed is actually quite idiomatic in Kotlin - there's no need to scope your function inside anything, top level functions are just fine to use for utilities, in fact, that's what most of the standard library consists of.
You've used the @JvmName
annotation the right way too, that's exactly how you're supposed to make these top level functions easily callable for Java users.
Note that you only need @JvmMultifileClass
if you are putting your top level functions in different files but still want them to end up grouped in the same class file (again, only for Java users). If you only have one file, or you're giving different names per file, you don't need this annotation.
If for some reason you want the same Utils.foo()
syntax in both Java and Kotlin, the solution with an object
and then @JvmStatic
per method is the way to do that, as already shown by @marianosimone in this answer.
You'd need to use @JvmStatic
for that:
In Kotlin:
object Utils {
@JvmStatic
fun foo(): Boolean = true
}
val test = Utils.foo()
In Java:
final boolean test = Utils.foo()
Note that the util class you used in Java was the only way to supply additional functions there, for anything that did not belong to a particular type or object. Using object
for that in Kotlin does not make any sense. It isn't a singleton, right?
The second approach you mentioned is rather the way to go for utility functions. Internally such functions get translated to static ones and as you can see they become the static util classes in Java you are searching for, as you can't have standalone functions in Java without a class or enum. In Kotlin itself however they are just functions.
Some even count utility classes to the anti-patterns. Functions on the other hand make totally sense without a class or object whose name hasn't so much meaning anyway.