4

I am wondering when should I use top-level const and when companion object? And should I consider what to use if the property is private or public?

const val URI = "sdfsdfsdf"

or should I use:

companion object {
    const val URI = "sdfsdfsdf"
}

and does it matter what to use when we are dealing with the visibility?

Shweta Chauhan
  • 6,739
  • 6
  • 37
  • 57
Artur A
  • 257
  • 3
  • 20
  • 2
    I prefer to use the constants in the top-level but I don´t know exactly if all plugins, but some plugins to calculate the test coverage use the .class files but when you using a const declaration in the top level of a class, internally it is created a kt class, so the coverage is reduzed because for the plugin the class has two parts = .class and another .kt, and the kt has a zero percent of coverage xD – Manuel Mato Apr 07 '20 at 15:36
  • 1
    a companion object is a singleton, in other words globally accessible and single instance everywhere, so i don't know if there is any difference between them since both have almost the same property. But for simplicity of calling the constant i'd prefer top-level – Animesh Sahu Apr 07 '20 at 15:41
  • What about the performance wise? – Artur A Apr 07 '20 at 15:45
  • 1
    Does this answer your question? [Kotlin: Difference between constant in companion object and top level](https://stackoverflow.com/questions/49969319/kotlin-difference-between-constant-in-companion-object-and-top-level) – Eyal Apr 07 '20 at 19:27

1 Answers1

7

According to JetBrains:

The recommended practice is to never use object for creating namespaces, and to always use top-level declarations when possible. We haven’t found name conflicts to be an issue, and if you do get a conflict, you can resolve it using an import with alias.

So based on that the answer to your initial question

When I should prefer top-level const [...]?

is always.

This is, however, a recommendation and in the end it's up to you how you want to organize your code and make use of the code completion feature in the IDE. Sometimes it's just better not to pollute your global namespace for the autocompletion sake. Since this problem/question has been widely discussed through many threads (e.g. here or here) and I'd say it heavily depends on one's preferences, I'll leave it here.

If you'd like to know what is happening under the hood, though, from bytecode perspective there is a slight difference between two approaches. Both top-level or (companion) object constants end up as static members of some class, but the object approach additionally creates a static INSTANCE field that holds the object's reference. Memory wise this shouldn't make much difference, but it's good to be aware of it.

jsamol
  • 3,042
  • 2
  • 16
  • 27
  • JetBrains says you will never have name conflicts. but for example when I want to create top level constants on top of 2 different classes in the same package I can't do it , compiler complains with message 'name conflicts' – Artur A Apr 09 '20 at 06:45
  • 1
    @ArturA The package structure doesn't necessarily have to be the same as the directory structure in Kotlin. So you can always create a separate namespace, even within the same directory. I guess that's why they say there will never be conflicts. – jsamol Apr 09 '20 at 07:45
  • @ArturA You mean an example of package names not matching the directory structure? I'd just edit my answer and put two classes with different package names there, which really wouldn't show anything. I'd suggest you setup a simple project for yourself in IntelliJ or AS, create two files in the same directory, change it's `package` names so they don't match anymore, and play with declarations and imports. You'll probably notice you'll be getting a warning saying _Package directive doesn't match file location_, which is quite amusing given the fact it's the recommended way to avoid conflicts. – jsamol Apr 09 '20 at 15:24
  • @ArturA Just to make it clear, as I've already said, declaring "everything" as top-level is merely a _recommendation_, so it's good to take it into consideration, but in the end readability, consistency and ease of use are the things that matter the most. – jsamol Apr 09 '20 at 15:41