相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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.

Additional info from @Roland answer: Using object for utils in Kotlin does not make any sense. It isn't a singleton, right? Thank you all\ – nhoxbypass Aug 13, 2018 at 3:03 Thank you, may be keep the Java style (UtilsClass.utilsFunc()) is not so good with Kotlin, because the UtilsClass part is redundant right? – nhoxbypass Aug 13, 2018 at 3:05 Well, at this point is almost a matter of taste/style. As @zsmb13 pointed out, you can get that syntax in Java by using @JvmName, and use the top level declaration in Kotlin. Some people still prefer the named object even in Kotlin, as it provides a more consistent style across a multi-language project. – marianosimone Aug 13, 2018 at 5:56

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.

I'm familiar with the Java style (UtilsClass.utilsFunc()) that group utils functions with relative meaning to the same class (for easy to manage). But it's not a good approach in Kotlin, right? – nhoxbypass Aug 13, 2018 at 3:10 Yes. Whereas in Java you had no other way to deliver such functions, in Kotlin you have. In Java you could at least have static imports to hide the utility class name and then the usage will look the same in Java as in Kotlin. This is probably the better approach then the other way around. – Roland Aug 13, 2018 at 6:00

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

 
推荐文章