Question
Java static final Equivalent in Kotlin: Constants with const val and Companion Objects
Question
In Java, a constant is often declared like this:
class Hello {
public static final int MAX_LEN = 20;
}
What is the Kotlin equivalent of this pattern?
More specifically:
- How do you declare a constant in Kotlin?
- When should you use
const valversusval? - Where should the constant be placed: top-level, inside an
object, or inside acompanion object?
Short Answer
By the end of this page, you will understand how Kotlin represents constants that are similar to Java static final fields. You will learn when to use const val, when a plain val is enough, and where constants are typically declared in Kotlin code such as top-level files, object declarations, and companion objects.
Concept
In Java, static final is commonly used for constants:
public static final int MAX_LEN = 20;
This combines two ideas:
static: the value belongs to the class, not to an instancefinal: the value cannot be reassigned
Kotlin does not have the static keyword in the same way Java does. Instead, Kotlin offers several ways to define values that behave like class-level constants.
The most direct equivalent for a compile-time constant is:
const val MAX_LEN = 20
A const val means:
- it is read-only
- its value is known at compile time
- it can be used in places that require a compile-time constant
Examples of allowed const val values include:
- strings
- numbers
- booleans
- chars
If a value is read-only but not known at compile time, use instead:
Mental Model
Think of Java static final as a value pinned to the wall of a room:
- static means everyone in the room shares the same pinned note
- final means nobody can replace the note
In Kotlin, you still pin the note in one shared place, but the language gives you different walls to pin it on:
- a file wall: top-level
const val - a category wall: inside an
object - a class-related wall: inside a
companion object
If the note must be written before the program starts and never change, use const val. If it is still read-only but created later, use val.
Syntax and Examples
The most common Kotlin forms are:
1. Top-level constant
const val MAX_LEN = 20
Use this when the constant does not need to belong to a specific class.
2. Inside an object
object Limits {
const val MAX_LEN = 20
}
Usage:
println(Limits.MAX_LEN)
This is useful for grouping related constants.
3. Inside a companion object
class Hello {
companion object {
const val MAX_LEN = 20
}
}
Usage:
println(Hello.MAX_LEN)
This is the closest style to a Java class constant.
4. Read-only but not compile-time constant
class {
{
maxLen = listOf(, ).max()
}
}
Step by Step Execution
Consider this example:
class Hello {
companion object {
const val MAX_LEN = 20
}
}
fun main() {
println(Hello.MAX_LEN)
}
Step by step:
class Hellodefines a class.- Inside it,
companion objectcreates a shared object associated with the class. const val MAX_LEN = 20defines a constant inside that companion object.- Because it is in the companion object, Kotlin lets you access it using the class name:
Hello.MAX_LEN. main()callsprintln(Hello.MAX_LEN).- The output is:
20
Now compare with a top-level constant:
const val MAX_LEN = 20
fun main() {
println(MAX_LEN)
}
Real World Use Cases
Constants like Java static final fields appear everywhere in Kotlin applications.
Common examples
- API paths
- error codes
- configuration keys
- default limits
- screen route names
- database column names
- intent/action names in Android
Example: API configuration
object ApiConfig {
const val BASE_URL = "https://api.example.com"
const val TIMEOUT_SECONDS = 30
}
Example: validation rules
class PasswordValidator {
companion object {
const val MIN_LENGTH = 8
}
}
Example: keys used across a project
object PreferencesKeys {
const val USER_TOKEN = "user_token"
const val THEME = "theme"
}
These constants make code easier to maintain because the value is defined once and reused everywhere.
Real Codebase Usage
In real Kotlin projects, developers usually choose the location of a constant based on meaning and scope.
Common patterns
Top-level constants
Used when the constant is shared and does not belong to one class.
const val DEFAULT_PAGE_SIZE = 20
This is common in utility files or package-level configuration.
Grouping with object
Used to organize related constants.
object HttpHeaders {
const val AUTHORIZATION = "Authorization"
const val CONTENT_TYPE = "Content-Type"
}
This avoids scattering unrelated constants across files.
Companion object for class-related values
Used when the constant logically belongs to a class.
class CacheManager {
companion object {
const val DEFAULT_CACHE_SIZE = 100
}
}
Validation and guard clauses
Constants are often used in checks.
Common Mistakes
Here are some common beginner mistakes when translating Java static final to Kotlin.
1. Using const with a non-constant expression
Broken code:
const val MAX_LEN = listOf(10, 20).max()
Why it fails:
const valrequires a compile-time constant- this value is computed at runtime
Correct version:
val maxLen = listOf(10, 20).max()
2. Expecting val to be the same as const val
val name = "Kotlin"
This is read-only, but not necessarily a compile-time constant in all contexts.
Use const val when the value is truly constant and allowed by Kotlin:
const NAME =
Comparisons
Here is a quick comparison of Kotlin options.
| Kotlin form | Mutable? | Compile-time constant? | Best use case |
|---|---|---|---|
const val | No | Yes | True constants like fixed strings and numbers |
val | No | No, not necessarily | Read-only values computed at runtime |
var | Yes | No | Values that must change |
Placement comparison
| Location | Example | Use when |
|---|---|---|
| Top-level |
Cheat Sheet
// Top-level compile-time constant
const val MAX_LEN = 20
// Grouped constants
object Limits {
const val MAX_LEN = 20
}
// Class-related constant
class Hello {
companion object {
const val MAX_LEN = 20
}
}
// Read-only runtime value
val maxLen = listOf(10, 20).max()
Rules
- Use
const valfor compile-time constants only. - Use
valfor read-only values computed at runtime. - Use
varonly when reassignment is needed. - Kotlin does not use Java-style
static. - Put constants at top level if they do not belong to a specific class.
- Use
objectto group related constants. - Use
companion objectif the constant belongs to a class.
Common valid const val types
FAQ
What is the Kotlin equivalent of Java static final?
Usually const val for true constants, often placed at top level or inside a companion object.
Should I use const val or val in Kotlin?
Use const val if the value is known at compile time. Use val if it is read-only but computed at runtime.
Does Kotlin have static fields?
Not in the Java syntax. Kotlin uses top-level declarations, object, and companion object instead.
Can I declare a constant inside a class in Kotlin?
Yes. Put it inside a companion object if you want class-style access like MyClass.MY_CONSTANT.
Can const val hold a custom object?
No. const val only works for compile-time constant values such as strings, numbers, booleans, and chars.
Is top-level const val better than ?
Mini Project
Description
Build a small Kotlin validation utility for user registration. The project demonstrates how to declare constants in idiomatic Kotlin using top-level constants, grouped constants in an object, and class-related constants in a companion object.
Goal
Create a simple program that validates username and password input using Kotlin constants declared in the most appropriate places.
Requirements
- Create at least one top-level constant for a general application rule.
- Create an
objectthat groups related text keys or messages. - Create a class with a
companion objectconstant used during validation. - Write a function that checks whether a username and password are valid.
- Print clear results for at least two test users.
Keep learning
Related questions
Accessing Kotlin Extension Functions from Java
Learn how Kotlin extension functions are compiled and how to call them correctly from Java with clear examples and common pitfalls.
Allow HTTP and HTTPS in Android 9 Pie with Network Security Configuration
Learn how Android 9 Pie handles cleartext HTTP traffic and how to allow HTTP and HTTPS safely using network security config.
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.