Question
In Kotlin, what is the recommended way to declare constants, and what naming convention should be used?
For example, inside a companion object, which style is preferred?
companion object {
// 1
val MY_CONST = "something"
// 2
const val MY_CONST = "something"
// 3
val myConst = "something"
}
Should one of these be used, or is there a better Kotlin-style approach?
Short Answer
By the end of this page, you will understand how constants are usually declared in Kotlin, when to use const val instead of val, where constants should live, and how Kotlin naming conventions differ for true constants versus regular read-only properties.
Concept
What is a constant in Kotlin?
In Kotlin, a constant usually means a value that:
- never changes
- is known at compile time
- can be inlined by the compiler
For this, Kotlin provides const val.
const val APP_NAME = "MyApp"
A regular val is read-only, but it is not automatically a compile-time constant.
val appName = "MyApp"
This means:
val= cannot be reassigned after initializationconst val= a special kind ofvalfor compile-time constants
Why this matters
Choosing between val and const val affects:
- clarity: other developers can immediately see whether a value is a true constant
- usage: some places require compile-time constants, such as annotations
- style: Kotlin has different naming conventions for constants and regular properties
Mental Model
Think of val and const val like two kinds of labels on boxes:
valmeans: this box gets one value, and you cannot replace it laterconst valmeans: this box is permanently filled with a simple value that was known before the program even started running
Another way to think about it:
valis a locked containerconst valis text printed directly into the program at compile time
That is why const val is stricter. Kotlin only allows it for simple values such as:
StringIntDoubleBoolean- other primitive-like compile-time values
If Kotlin has to run code to get the value, then it is no longer a const val.
Syntax and Examples
Core syntax
const val
Use this for real compile-time constants:
const val BASE_URL = "https://api.example.com"
const val MAX_COUNT = 10
val
Use this for read-only properties:
val username = "alice"
val createdAt = System.currentTimeMillis()
Inside an object
object Config {
const val API_KEY_HEADER = "X-API-Key"
val timeoutMillis = 5000L
}
Inside a companion object
class ApiClient {
companion object {
DEFAULT_TIMEOUT =
defaultHeaders = listOf()
}
}
Step by Step Execution
Traceable example
class AppConfig {
companion object {
const val APP_NAME = "DemoApp"
val launchTime = System.currentTimeMillis()
}
}
fun main() {
println(AppConfig.APP_NAME)
println(AppConfig.launchTime)
}
What happens step by step
1. Kotlin sees const val APP_NAME = "DemoApp"
- This is a compile-time constant.
- The value is simple and known immediately.
- Kotlin treats it as a true constant.
2. Kotlin sees val launchTime = System.currentTimeMillis()
- This is read-only, but not a compile-time constant.
- The value is created when the program runs.
- Kotlin cannot mark this as
const.
3. main() prints AppConfig.APP_NAME
- The constant value is accessed directly.
- It is always
"DemoApp".
4. main() prints
Real World Use Cases
Common places constants are used
Configuration keys
const val PREF_USER_TOKEN = "user_token"
const val PREF_THEME = "theme"
These are fixed strings used in settings or shared preferences.
API field names and headers
const val HEADER_AUTHORIZATION = "Authorization"
const val CONTENT_TYPE_JSON = "application/json"
Useful when the same literal appears in many places.
Intent extras or navigation keys
const val EXTRA_USER_ID = "extra_user_id"
This avoids typos when passing values between screens.
Limits and defaults
const val MAX_LOGIN_ATTEMPTS = 5
const val DEFAULT_PAGE_SIZE = 20
These values are fixed business rules or defaults.
Real Codebase Usage
How developers commonly use constants in real projects
1. Group related constants in object
object ApiConstants {
const val BASE_URL = "https://api.example.com"
const val USERS_PATH = "/users"
}
This keeps related values organized.
2. Use top-level constants for file-wide shared values
const val SECONDS_IN_MINUTE = 60
This is simple and avoids unnecessary wrappers.
3. Use companion object for class-specific constants
class UserRepository {
companion object {
const val CACHE_KEY = "user_repo_cache"
}
}
This is useful when the constant belongs conceptually to that class.
4. Use regular val for computed read-only values
Common Mistakes
1. Using uppercase names for regular val
Broken style example:
companion object {
val MY_CONST = "something"
}
Why this is a problem:
- the uppercase name suggests a true constant
- but
valis only read-only, not necessarily compile-time constant
Better:
companion object {
const val MY_CONST = "something"
}
Or, if it is not a compile-time constant:
companion object {
val myConst = createValue()
}
2. Trying to use const val with runtime values
Broken code:
const val START_TIME = System.currentTimeMillis()
This fails because System.currentTimeMillis() is only known at runtime.
Comparisons
const val vs val
| Feature | const val | val |
|---|---|---|
| Reassignable | No | No |
| Compile-time constant | Yes | Not necessarily |
| Can use runtime computation | No | Yes |
| Naming convention | UPPER_SNAKE_CASE | camelCase |
| Good for annotations and fixed literals | Yes | Usually no |
Top-level vs object vs companion object
Cheat Sheet
Quick rules
- Use
const valfor compile-time constants. - Use
valfor read-only values that are computed at runtime or are unsupported byconst. - Name
const valwithUPPER_SNAKE_CASE. - Name normal
valproperties withcamelCase. - Prefer top-level constants unless the constant clearly belongs to a class or group.
Syntax
const val MAX_SIZE = 100
val currentSize = getSize()
Valid const val examples
const val APP_NAME = "Demo"
const val RETRY_LIMIT = 3
const val PI_APPROX = 3.14
const val ENABLE_LOGGING = true
Invalid const val examples
FAQ
Should I always use const val instead of val in Kotlin?
No. Use const val only for true compile-time constants. Use val for read-only values that are computed at runtime or use unsupported types.
What is the Kotlin naming convention for constants?
Use UPPER_SNAKE_CASE for const val, such as MAX_RETRIES. Use camelCase for regular val properties.
Is val a constant in Kotlin?
Not exactly. val means read-only after initialization, but it may still be initialized at runtime, so it is not necessarily a compile-time constant.
Can I declare const val inside a class?
Not as a normal instance property. It is typically declared at the top level, inside an object, or inside a companion object.
When should I use a top-level constant in Kotlin?
Use a top-level constant when the value does not logically belong to any specific class.
Can hold a list or object?
Mini Project
Description
Create a small Kotlin configuration file for an app. The goal is to practice deciding which values should be const val and which should remain regular val properties. This mirrors real projects where some values are fixed constants and others are loaded or computed at runtime.
Goal
Build a simple app settings structure that uses const val for true constants and val for runtime values.
Requirements
- Create at least two true constants using
const val - Group at least one set of constants inside an
object - Add one runtime-computed read-only value using
val - Print all values from a
main()function
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.