Hi, Frankly I don’t see the benefit of const taken...
# announcements
j
Hi, Frankly I don’t see the benefit of const taken into account only primitives and String type are allowed. Can someone shed a light why there is such constraint on const ? Many times I started with a const which complied with the restriction, and then when I try to type migration refactor, say, a String type constant to a specific type I end up getting a compilation error. See an example below. And then I have to come up with another thing, which requires a significant refactor, and all this just because of this restriction. Is this related to constant expression in java language?
Copy code
class A {
    companion object {
        const val name1 = "Antonel"
        const val name2 = StringBuilder("Antonel")
    }
}
error: const 'val' has type 'kotlin.text.StringBuilder /* = java.lang.StringBuilder */'. Only primitives and String are allowed
Antonel.
r
I suppose Constants need to be stable values at compile time therefore only literals are allowed since
StringBuilder(...)
is a runtime computation and can't be resolved at compile time.
s
const val
seems to be useful in cases where it’s beneficial to reuse or otherwise extract the use of string literals to a variable, but still use that string where a compile-time constant is required
👍 1
Annotations, for example
Raul has the right idea that invocations of
StringBuilder(...)
can’t be resolved at compile-time - can’t put a string builder in something like the
.data
segment after all
j
This was my impression as well - it has to be a constant expression. But I am wondering if the const support in kotlin could be improved (even if the performance is going to degrade). I am wondering if the kotlin compiler can be enhanced so as: 1. if the type of the constant is String or primitives -> compile to constant expression. 2. otherwise end up with smth like private static final …. equivalent in java. For me const in companion object (or plain object) is quite misleading: which is the difference between
Copy code
const val a = "a" and
@JvmStatic val a = "a"?
with @JvmStatic there is no restriction and both assignments seems to have the same intention.
a
const
means a value can be folded into other constant expressions -
@JvmStatic
adds static accessors to the companion’s class. So they are distinct things. Look at the decompilation of:
Copy code
object Things {
    val propertyName = "things.key"
    const val constPropertyName = "things.const_key"
    @JvmStatic val staticPropertyName = "things.const_key"
}

fun main(args: Array<String>) {
    println(Things.propertyName)
    println("property: ${Things.propertyName}")

    println(Things.constPropertyName)
    println("property: ${Things.constPropertyName}")

    println(Things.staticPropertyName)
    println("property: ${Things.staticPropertyName}")
}
You’ll see that
const_key
is referenced directly in the main code (so if the const was in a library, and the library changed it, the app wouldn’t reflect that)
j
Thank you Steve for the explanation. I used show the kotlin bytecode in Idea and things are clear now.