What is the difference between file level: val myV...
# getting-started
b
What is the difference between file level: val myVariable = “const” const val myVariable = “const”
j
const
defines a compile-time constant. This means the value is inlined at compile time in every usage site.
e
const
is a compile-time constant, which only works for specific types and can be used in annotations. on JVM, it is a
static final
that the Java language will inline into callsites. a non-
const
val
is a read-only property and its containing object must be initialized to set its value. callsites are not inlined (which is slightly better for incremental compilation) and it cannot be used in annotations.
j
Note that
const
has an important consequence: if module A uses a 
const val
 declared in module B, and the value of the constant is later changed in module B, then module A needs to be recompiled against the new version of module B to see the change. Otherwise, A would still use the old constant value, even if the new module B is on the classpath.
e
of note, Java
static final
fields may or may not be compile-time constants depending on their initializer; Kotlin clearly separates the two, which is IMO a strict win (it has ABI compatibility implications)
g
Also, there is another option, which I prefer for both cases when I need immutable constant value:
Copy code
val myVariable get() = "const"
It doesn’t affect incremental compilation if “const” value is changes unlike
const val
and it doesn’t create unnecessary field to keep constant value, only getter which returns value
c
@gildor also, JVMs tend to inline a lot of stuff at runtime, so the getter call probably never exists if it's called often enough for that to make a difference
g
Yep, it’s true
e
can't refer to names in annotations unless they're
const
(and Java can't use non-
const
in
switch
but that's not an issue for Kotlin/`when`) otherwise yeah, a simple getter is easily optimized away, and I like it over a val with constant backing field