Constants in Kotlin: How to Create Them Correctly? A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Constants in Kotlin: Stop Guessing, Start Using Them Correctly

\n\n

If you've been writing in Kotlin for at least a week, you've almost certainly encountered the question: "How do I properly declare a constant?" It seems simple enough — there's val, there's const val, there's companion object. But the devil, as always, is in the details. And this question on Stack Overflow has gathered thousands of views for a reason.

\n\n

Let's finally figure out what ways of creating constants exist in Kotlin, when to use which, and why val is not always a constant. Let's go!

\n\n

1. val vs const val: What's the Catch?

\n\n

The most common question from beginners: "I wrote val — isn't that a constant?" The answer: yes and no.

\n\n

val is an immutable reference (read-only). But the value is computed at runtime. That means it's not a compile-time constant.

\n\n
// This is NOT a compile-time constant\nval currentTime = System.currentTimeMillis()
\n\n

const val is a real constant that is inlined into the code at compile time (like static final in Java).

\n\n
// But this IS a constant\nconst val PI = 3.14159
\n\n

Important limitation: const val can only be used with primitive types and String. No objects, lists, or custom classes.

\n\n
\n

💡 Golden rule: If the value is known at compile time — use const val. If it's computed at runtime — use val.

\n
\n\n

2. Where to Declare Constants? Top 3 Ways

\n\n

Way 1: Top-level Constants (Recommended)

\n\n

The simplest and cleanest way is to declare a constant at the top level of a file. No classes, no objects — just a file with constants.

\n\n
// Constants.kt\nconst val BASE_URL = "https://api.example.com"\nconst val TIMEOUT_SECONDS = 30\nconst val APP_NAME = "MyKotlinApp"
\n\n

Why is this great?

\n
    \n
  • Minimal code
  • \n
  • Accessible from everywhere without prefixes
  • \n
  • The compiler inlines the values
  • \n
  • Easy to refactor
  • \n
\n\n

Way 2: companion object Inside a Class

\n\n

A classic approach from Java that migrated to Kotlin. Use it when constants are logically related to a class.

\n\n
class NetworkClient {\n    companion object {\n        const val DEFAULT_PORT = 8080\n        const val PROTOCOL = "https"\n    }\n}\n\n// Usage\nval port = NetworkClient.DEFAULT_PORT
\n\n

Downside: syntactic noise. Upside: constants are tied to a context.

\n\n

Way 3: object (Singleton) for Groups of Constants

\n\n

When there are many constants and they need to be grouped by meaning.

\n\n
object AppConstants {\n    const val MAX_LOGIN_ATTEMPTS = 5\n    const val SESSION_DURATION = 3600L\n    const val DATE_FORMAT = "yyyy-MM-dd"\n\n    object Urls {\n        const val LOGIN = "/auth/login"\n        const val LOGOUT = "/auth/logout"\n    }\n}\n\n// Usage\nAppConstants.Urls.LOGIN
\n\n

3. Constants in Android: Specifics

\n\n

If you're writing for Android, there are a few additional nuances.

\n\n

Constants in companion object and @JvmStatic

\n\n

To make a constant from a companion object a true static in Java (e.g., for annotations), use @JvmStatic:

\n\n
class MyFragment : Fragment() {\n    companion object {\n        @JvmStatic\n        const val ARG_ID = "id"\n    }\n}
\n\n

Constants in Resources

\n\n

Don't forget the classic Android way — resources. For strings, colors, dimensions:

\n\n
// strings.xml\n<string name="app_name">MyApp</string>\n\n// In code\nval appName = getString(R.string.app_name)
\n\n

But these are not compile-time constants.

Blogs

Book Recommendations