Kotlin provides two keywords, const val
and val
, for defining constants. While both are used to declare immutable values, there are significant differences between them in terms of usage, initialization, and behavior at runtime. In this blog, we will break down these differences with examples to help you choose the right one for your use case.
const val
: Compile-Time ConstantsThe const val
keyword is used to define compile-time constants. These constants are evaluated and assigned during compilation and cannot be changed at runtime.
Must be a top-level declaration or defined in a companion object
.
The value must be a primitive type (e.g., Int
, Double
, String
) or a String literal.
Cannot use functions or expressions for initialization.
Can be inlined and directly substituted into the bytecode at compile time.
const val API_URL = "https://api.example.com"
const val MAX_RETRY_COUNT = 3
fun main() {
println("API URL: $API_URL")
println("Max Retry Count: $MAX_RETRY_COUNT")
}
The const val
value is replaced directly in the bytecode, making it faster and more efficient as no memory allocation occurs for the constant.
val
: Runtime-Initialized ConstantsThe val
keyword is used to declare read-only properties that are initialized at runtime. Once initialized, their value cannot be changed.
Can be declared at any scope: top-level, inside a class, or in a function.
Can use complex expressions, function calls, or external data for initialization.
The initialization happens at runtime, and the value is stored in memory.
val currentTime: Long = System.currentTimeMillis()
val dynamicMessage: String = "Current time in milliseconds: $currentTime"
fun main() {
println(dynamicMessage)
}
Unlike const val
, the value of val
is not substituted at compile time but instead initialized when the code is executed.
const val
vs. val
const val
When:You need compile-time constants for configurations or fixed values, like URLs, file paths, or constants used in annotations.
Example:
const val PI = 3.14159
const val API_VERSION = "v1"
val
When:The value depends on runtime data, like timestamps, dynamic configurations, or results of function calls.
Example:
val userName = System.getProperty("user.name")
val randomValue = (1..100).random()
Can I use const val
for non-primitive types?
No, const val
only works with primitives and String literals. If you need a constant reference for an object, consider using val
or object
.
Is val
immutable?
Yes, the reference is immutable, but if the type is mutable (e.g., a List
), its content can change.
Example:
val mutableList = mutableListOf(1, 2, 3)
mutableList.add(4) // The list's content can change
Does const val
improve performance?
Yes, because const val
values are inlined and do not involve memory allocation.
Understanding the differences between const val
and val
is crucial for writing efficient and maintainable Kotlin code. Use const val
for fixed compile-time constants and val
for runtime-initialized, read-only properties. Choosing the right one ensures better performance and clarity in your code.
Akshay Nandwana
Founder AndroidEngineers
You can connect with me on:
Join our upcoming classes
https://www.androidengineers.in/courses