https://kotlinlang.org logo
#getting-started
Title
# getting-started
e

ermac10k

04/28/2021, 9:35 AM
Hello! who can explain what is a main aim of the ‘const’ word? i know the mechanism (compile time and no getter method). But i cannot understand when it is useful.
j

Jonathan Olsson

04/28/2021, 9:38 AM
The word is used for creating a ... constant. If you want to learn more about the utility of constants, wikipedia has a great article: https://en.wikipedia.org/wiki/Constant_(computer_programming)
💩 1
c

crummy

04/28/2021, 9:42 AM
that description seems to match
val
in Kotlin though, while
const
is something different, right?
p

Pavel Sidyakin

04/28/2021, 9:45 AM
It used at compile time and compiler can optimize code depending on the const value. It can remove "if" branches, for example. For example, to remove logging call completely (i.e. the logging code won't present in the compiled code), you can do something like this:
Copy code
const val DEBUG_LOG_ENABLED = BuildConfig.BUILD_TYPE == "debug"

inline fun debugLog(block: LogWrapper.() -> Unit) {
    if (DEBUG_LOG_ENABLED) LogWrapper.block()
}
If you remove "const" runtime check will be occurred.
v

Vampire

04/28/2021, 9:49 AM
Will that really work?
const
has to be a compile-time constant. So this shouldn't compile, should it? Unless maybe if
BUILD_TYPE
is a
const
too.
p

Pavel Sidyakin

04/28/2021, 9:50 AM
Of course BUILD_TYPE is const too
BTW, because of stupid solution of AGP developers, we can't use "DEBUG" property here
Copy code
public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String BUILD_TYPE = "debug";
}
e

ermac10k

04/28/2021, 9:52 AM
it’s synthetic a lot what is the real speed up of such manoeuvre?
p

Pavel Sidyakin

04/28/2021, 9:57 AM
Yes. If you have much debug logs, removing of the logging code in compile time increases performance. The approach removes the logging completely, including messages' stringbuilder
e

ermac10k

04/28/2021, 9:59 AM
j

Jonathan Olsson

04/28/2021, 11:35 AM
that description seems to match 
val
 in Kotlin though, while 
const
 is something different, right?
val
is a read-only local variable. Compare that to
const
: https://kotlinlang.org/docs/properties.html#compile-time-constants I would assume a
val
is similar to a Java
final
and a
const
would most closely resemble a
static final
? I don't really know why the poopwas given to the wikipedia article, but I might be missing some context related to the question. Besides the optimisations already known to OP
const
has great semantic utility. At least, that is my view of it.
e

ermac10k

04/28/2021, 11:37 AM
static final ~ companion object { val ... }
fyi
j

Jonathan Olsson

04/28/2021, 11:38 AM
Yes, I know. But Java doesn't have constants.
So semantically, what is achieved in Java with
static final
would probably better be replaced by
const
in a kotlin program.
e

ermac10k

04/28/2021, 11:39 AM
Exactly! And this is why I am interesting in kotlin devs motivation to invent it
j

Jonathan Olsson

04/28/2021, 11:43 AM
Ah, I see. My guess would be that it is related to a main difference of Kotlin vs Java: that not everything has to be a class. Consider this:
Copy code
class A {
    companion object {
        val MY_CONSTANT = 123
    }
}
compared to this:
Copy code
const val MY_CONSTANT = 123
v

Vampire

04/28/2021, 11:47 AM
You can also do
Copy code
val MY_CONSTANT = 123
The question is whether you want to have
MY_CONSTANT
in the
A
namespace or not
But it is still not a compile time constant that the compiler can inline
const
is like a
static final
in Java for which you use upper-case letters, as you should usually just use that for real constants and not for any
static final
.
p

Pavel Sidyakin

04/28/2021, 11:59 AM
BTW, you can't use non-const for annotations. OK:
Copy code
const val QUERY = "SELECT id FROM table"

@Dao
interface ADao {
    @Query(QUERY)
    fun query(): Int
}
Won't compile:
Copy code
val QUERY = "SELECT id FROM table"

@Dao
interface ADao {
    @Query(QUERY)
    fun query(): Int
}
e

ermac10k

04/28/2021, 12:41 PM
ok! is there any sense to write so:
companion object { const val ABC = "abc" }
disclaimer: it’s not my code 😉
v

Vampire

04/28/2021, 12:45 PM
Sure, why not? It is still a compile-time constant that you can use where you can use compile time constants with the compile-time optimizations in place and it is namespaced to the class of which this is a companion object
If you add
private
, then I'd say it is non-sense clutter and a top-level
private const val
would achieve the same
e

ephemient

04/28/2021, 3:01 PM
Java does have constants, `final int`/`final String` fields with compile-time constant non-null values will be marked in the resulting .class file and inlined at use sites
however Java doesn't have the ability to mark a final field as non-inlined (for future API compatibility reasons, for example) while giving it a compile-time constant non-null value... without hacks like what AGP does (
Boolean.parseValue("false")
)
Kotlin clearly distinguishes the cases with
const val
vs
val
e

ermac10k

04/29/2021, 5:06 AM
thx for all the answers!
3 Views