Skip to main content

Kotlin Constants

Constants play a vital role in programming, allowing us to define values that won't change throughout the execution of our program. In Kotlin, constants help make your code more readable, maintainable, and efficient.

Introduction to Constants

A constant is a variable whose value cannot be changed after it's assigned. Using constants in your code offers several benefits:

  • Readability: Meaningful constant names make code easier to understand
  • Maintainability: Changing a value in one place affects all usages
  • Prevention of errors: Prevents accidental value modifications
  • Performance: Some types of constants are evaluated at compile-time

Let's explore how Kotlin handles constants and the different ways to declare them.

Val vs Const in Kotlin

Kotlin provides two main ways to work with constant values:

  1. Using the val keyword (read-only variables)
  2. Using the const val modifier (compile-time constants)

Read-Only Variables with val

The val keyword creates a read-only variable that can be assigned only once:

kotlin
fun main() {
val pi = 3.14159
println("The value of pi is $pi")

// This would cause a compilation error:
// pi = 3.14 // Error: Val cannot be reassigned
}

Output:

The value of pi is 3.14159

While val creates a variable that cannot be reassigned, it's important to understand that the object it references may still be mutable:

kotlin
fun main() {
val languages = mutableListOf("Kotlin", "Java")
println("Original list: $languages")

// We can modify the list contents even though the reference is a val
languages.add("Python")
println("Modified list: $languages")

// But we cannot reassign languages to a new list
// languages = mutableListOf("C++") // Error: Val cannot be reassigned
}

Output:

Original list: [Kotlin, Java]
Modified list: [Kotlin, Java, Python]

Compile-Time Constants with const val

For true constants that are known at compile-time, Kotlin offers the const modifier:

kotlin
// Constants declared at the top level or as members of an object
const val MAX_USERS = 100
const val APP_NAME = "Kotlin Demo"
const val VERSION = "1.0.0"

fun main() {
println("Welcome to $APP_NAME version $VERSION")
println("This application supports up to $MAX_USERS users")
}

Output:

Welcome to Kotlin Demo version 1.0.0
This application supports up to 100 users

Restrictions on const val

There are several important restrictions when using const val:

  1. It can only be used with primitive types and String
  2. It must be declared at the top level or in an object declaration or companion object
  3. It cannot be assigned a function call or any other complex expression
  4. It cannot be a property with a custom getter

Here's what's allowed and what's not:

kotlin
// Allowed - primitive types and strings
const val MAX_COUNT = 100
const val SERVICE_URL = "https://api.example.com"
const val IS_DEBUGGING = true

// Not allowed - complex types
// const val DATE_NOW = Date() // Error: Only primitives and strings allowed

object Constants {
// Allowed - inside an object
const val TIMEOUT = 30_000
}

class Configuration {
companion object {
// Allowed - inside companion object
const val API_KEY = "ab12cd34ef56"
}

// Not allowed - inside a regular class
// const val DATABASE = "users" // Error: Const not allowed here
}

Practical Use Cases for Constants

Let's explore some real-world scenarios where constants are particularly useful:

1. Configuration Values

kotlin
object AppConfig {
const val API_BASE_URL = "https://api.myservice.com/v1/"
const val CONNECTION_TIMEOUT = 15_000 // 15 seconds in milliseconds
const val DEFAULT_PAGE_SIZE = 20
const val MAX_RETRY_ATTEMPTS = 3
}

fun fetchData() {
println("Connecting to ${AppConfig.API_BASE_URL}")
println("Timeout set to ${AppConfig.CONNECTION_TIMEOUT}ms")
// In a real application, these values would be used to configure network requests
}

2. Default Values and Boundaries

kotlin
class UserProfile {
companion object {
const val MIN_PASSWORD_LENGTH = 8
const val MAX_USERNAME_LENGTH = 30
const val DEFAULT_AVATAR = "default_avatar.png"
}

fun validatePassword(password: String): Boolean {
return password.length >= MIN_PASSWORD_LENGTH
}

fun validateUsername(username: String): Boolean {
return username.isNotEmpty() && username.length <= MAX_USERNAME_LENGTH
}
}

fun main() {
val profile = UserProfile()
println("Is 'pass123' a valid password? ${profile.validatePassword("pass123")}")
println("Is 'thisIsAReallyLongUsernameThatExceedsTheLimit' valid? ${profile.validateUsername("thisIsAReallyLongUsernameThatExceedsTheLimit")}")
}

Output:

Is 'pass123' a valid password? false
Is 'thisIsAReallyLongUsernameThatExceedsTheLimit' valid? false

3. Mathematical Constants

kotlin
object MathConstants {
const val PI = 3.14159
const val E = 2.71828
const val GOLDEN_RATIO = 1.61803
}

fun calculateCircleArea(radius: Double): Double {
return MathConstants.PI * radius * radius
}

fun main() {
val radius = 5.0
val area = calculateCircleArea(radius)
println("The area of a circle with radius $radius is $area")
}

Output:

The area of a circle with radius 5.0 is 78.53975

Best Practices for Using Constants

When working with constants in Kotlin, consider these best practices:

  1. Use meaningful names: Choose descriptive names, typically in UPPER_SNAKE_CASE for constants.

  2. Group related constants: Place related constants in objects or companion objects to organize them logically.

  3. Choose the right type:

    • Use const val for compile-time constants (primitive types and strings)
    • Use val for runtime constants and non-primitive types
  4. Consider visibility modifiers:

    • Mark constants as private if they should only be used within a class
    • Use internal for module-level visibility
  5. Document complex constants: Add comments to explain non-obvious values or calculations.

kotlin
object NetworkConfig {
/**
* Default timeout for network connections in milliseconds.
* Set to 30 seconds based on average response time analysis.
*/
const val DEFAULT_TIMEOUT = 30_000

/**
* Maximum number of retry attempts before considering a request failed.
*/
const val MAX_RETRY_COUNT = 3
}

Summary

Constants are essential elements in Kotlin programming that help create more readable, maintainable, and efficient code. In this guide, we've explored:

  • The difference between val (read-only variables) and const val (compile-time constants)
  • Restrictions and requirements for using const val
  • Practical use cases for constants in real applications
  • Best practices for working with constants

By properly using constants in your Kotlin programs, you create code that's easier to maintain, less error-prone, and more self-documenting.

Exercises

To reinforce your understanding of Kotlin constants, try these exercises:

  1. Create an object called UIConstants that contains constants for common UI values like default padding, text sizes, and animation durations.

  2. Refactor the following code to use constants where appropriate:

    kotlin
    fun calculateTotal(price: Double): Double {
    return price + price * 0.07
    }

    fun isEligibleForDiscount(purchaseTotal: Double): Boolean {
    return purchaseTotal > 100.0
    }
  3. Create a GameSettings class with a companion object containing game configuration constants, and a few methods that use these constants.

Additional Resources

Happy coding with Kotlin constants!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)