Question
In Kotlin, what is the difference between const and val?
I recently read about the const keyword and got confused. Both const and val seem to be used for immutable values, so it is not obvious what practical difference exists between them. Am I missing an important distinction?
For example:
val name = "Kotlin"
const val APP_NAME = "MyApp"
When should each one be used, and what rules apply to const?
Short Answer
By the end of this page, you will understand that val means a read-only reference, while const val means a compile-time constant in Kotlin. You will learn where const is allowed, what types it supports, why it is more restrictive than val, and how developers typically use each one in real Kotlin codebases.
Concept
val and const val are related, but they are not the same thing.
valmeans the variable can be assigned once.const valmeans the value is not only assigned once, but is also known at compile time.
val: read-only reference
A val creates a read-only reference. Once a value is assigned, you cannot reassign that variable.
val username = "alice"
// username = "bob" // Error
However, the value assigned to a val does not have to be known at compile time.
val currentTime = System.currentTimeMillis()
This is valid because currentTime is assigned only once, even though Kotlin can only get the value when the program runs.
const val: compile-time constant
A const val is a special kind of .
Mental Model
Think of val as a label on a box that cannot be moved to another box.
- You attach the label once.
- After that, the label must always point to the same thing.
- But the thing inside may have been created at runtime.
Think of const val as a value printed in the instruction manual before the program even starts.
- The value is fixed ahead of time.
- The compiler already knows it.
- It can copy that value directly wherever needed.
So:
val= fixed referenceconst val= fixed compile-time literal
Syntax and Examples
Basic syntax
val siteName = "Example"
const val APP_NAME = "MyApplication"
Example 1: regular val
val timestamp = System.currentTimeMillis()
println(timestamp)
This works because timestamp is assigned once. Its value is decided when the program runs.
Example 2: const val
const val DEFAULT_PORT = 8080
const val BASE_URL = "https://api.example.com"
These work because the values are compile-time constants.
Example 3: invalid const val
const val createdAt = System.currentTimeMillis() // Error
This fails because function calls are evaluated at runtime, not compile time.
Where can be declared
Step by Step Execution
Consider this code:
const val TAX_RATE = 0.2
fun main() {
val price = 100.0
val total = price + (price * TAX_RATE)
println(total)
}
Step by step
-
const val TAX_RATE = 0.2- Kotlin reads this as a compile-time constant.
- The value
0.2is fixed and known before execution.
-
val price = 100.0- When
main()runs,priceis created. - It cannot be reassigned later.
- When
-
val total = price + (price * TAX_RATE)- Kotlin uses
pricefrom runtime. - It uses
TAX_RATEas a constant value. - The expression becomes
100.0 + (100.0 * 0.2).
- Kotlin uses
Real World Use Cases
When to use val
Use val for most read-only values in normal application code:
- results from a database query
- user input after validation
- API response data
- generated timestamps
- parsed configuration values
Example:
val userId = request.getParameter("id")
val createdAt = System.currentTimeMillis()
When to use const val
Use const val for fixed values that never change and are known ahead of time:
- API endpoint paths
- intent keys
- database column names
- request timeout defaults
- error codes
- annotation arguments
Example:
const val EXTRA_USER_ID = "extra_user_id"
const val RETRY_LIMIT = 3
const val TABLE_NAME = "users"
Android example
Keys {
USER_ID =
SESSION_TOKEN =
}
Real Codebase Usage
In real Kotlin projects, developers usually prefer val by default and reserve const val for true constants.
Common patterns
Configuration constants
object Defaults {
const val PAGE_SIZE = 20
const val CACHE_DURATION_MINUTES = 60
}
Keys and identifiers
object JsonFields {
const val NAME = "name"
const val EMAIL = "email"
}
Companion object constants
class Logger {
companion object {
const val TAG = "Logger"
}
}
Guard clauses with val
{
safeName = name ?:
println(safeName)
}
Common Mistakes
1. Thinking val means deeply immutable
val prevents reassignment of the reference, but the object itself may still be mutable.
val numbers = mutableListOf(1, 2, 3)
numbers.add(4) // Valid
// numbers = mutableListOf(5, 6) // Error
Avoid confusion by remembering:
valprotects the variable reference- it does not automatically make the object immutable
2. Using const with runtime expressions
Broken example:
const val NOW = System.currentTimeMillis()
Why it fails:
System.currentTimeMillis()is only known at runtime.
Use this instead:
val now = System.currentTimeMillis()
3. Declaring const in the wrong place
Comparisons
| Feature | val | const val |
|---|---|---|
| Reassignment allowed? | No | No |
| Known at compile time? | Not required | Required |
| Can use runtime function calls? | Yes | No |
| Allowed for local variables? | Yes | No |
| Allowed types | Any type | Primitive types and String |
| Can be used in annotations? | Usually no | Yes |
| Typical use | Read-only values | Fixed constants |
var vs vs
Cheat Sheet
Quick rules
val= assign onceconst val= assign once and known at compile time- every
const valis also effectively aval - not every
valcan beconst
Use val when
val now = System.currentTimeMillis()
val user = getUser()
val total = price * quantity
Use const val when
const val APP_NAME = "Demo"
const val MAX_RETRIES = 3
const val API_PATH = "/users"
const val rules
- must be known at compile time
- must be primitive or
String
FAQ
Is const the same as val in Kotlin?
No. const val is a compile-time constant, while val is only a read-only reference.
Can I use const inside a function?
No. const val cannot be declared as a local variable inside a function.
Can a val be calculated at runtime?
Yes. A val can store the result of a function call or any runtime expression.
Why would I use const val instead of val?
Use const val when the value is fixed, known at compile time, and needs to behave like a real constant, such as in annotation arguments or shared constant keys.
Can const val hold a list or object?
No. const val only supports primitive types and String.
Is val always immutable?
The reference is immutable, but the object it points to may still be mutable.
Mini Project
Description
Build a small Kotlin constants file for an app configuration module. This project demonstrates when to use const val for fixed application constants and when to use regular val for values computed at runtime.
Goal
Create a simple program that stores fixed app settings with const val and calculates runtime values with val.
Requirements
- Define at least two
const valvalues for fixed application settings. - Define at least two
valvalues that are computed when the program runs. - Print all values to show the difference in usage.
- Keep
const valdeclarations in valid locations. - Use only valid Kotlin syntax.
Keep learning
Related questions
Android AlarmManager Example: Scheduling Tasks with AlarmManager
Learn how to use Android AlarmManager to schedule tasks, set alarms, and handle broadcasts with a simple beginner example.
Can You Extend a Data Class in Kotlin? Inheritance, Limits, and Better Alternatives
Learn why Kotlin data classes cannot be extended, what causes the component function clash, and which alternatives to use instead.
Difference Between List and Array in Kotlin
Learn the difference between List and Array in Kotlin, including mutability, size, APIs, performance, and when to use each one.