Menu
Coddy logo textTech

Constants With const

Part of the Object Oriented Programming section of Coddy's Kotlin journey. Lesson 14 of 57.

const val declares a compile-time constant: a value that is fixed when the program is compiled. It is allowed at the top level of a file and inside an object or companion object, and only for the basic types such as Int, Double and Boolean, and for String:

const val MAX_PLAYERS = 4

class Lobby {
    val players = mutableListOf<String>()

    fun canStart() = players.size in MIN_PLAYERS..MAX_PLAYERS

    companion object {
        const val MIN_PLAYERS = 2
    }
}

Inside main:

val lobby = Lobby()
lobby.players += listOf("ada", "bo")
println(lobby.canStart())
println("${Lobby.MIN_PLAYERS}-$MAX_PLAYERS players")

Output:

true
2-4 players

Constants are named in UPPER_SNAKE_CASE. const is stricter than val: the value must be known without running any code, so a function call or a list is not allowed. A val in an object is shared and read-only too, and accepts any value:

const val GREETING = "Hello"                  // a String literal
const val TIMEOUT_MS = 30 * 1000              // computed from literals
// const val START = System.nanoTime()        // error: not a constant
// const val DAYS = listOf("Mon", "Tue")      // error: only basic types and String
object Defaults {
    val DAYS = listOf("Mon", "Tue")           // a shared read-only val
}

A companion object can also hold shared mutable state. Every instance reads and changes the same property, which suits counters and caches. This class keeps one instance per name, so asking twice returns the same object (=== checks that two references point to one object):

class Tile private constructor(val name: String) {
    companion object {
        private val cache = mutableMapOf<String, Tile>()
        val created: Int
            get() = cache.size

        fun of(name: String) = cache.getOrPut(name) { Tile(name) }
    }
}

Inside main:

val a = Tile.of("grass")
val b = Tile.of("grass")
Tile.of("water")
println(a === b)
println(Tile.created)

Output:

true
2

Top level or companion? A top-level constant or function belongs to its file and is used by its plain name in every file of the package. Put a constant in a companion when it belongs to one class: callers write Lobby.MIN_PLAYERS, which says where the value comes from, and a private const val stays inside that class.

// Limits.kt
const val MAX_UPLOAD_MB = 25                 // used everywhere as MAX_UPLOAD_MB

// Lobby.kt
class Lobby {
    companion object {
        const val MIN_PLAYERS = 2            // used as Lobby.MIN_PLAYERS
        private const val ROOM_PREFIX = "L-" // only inside Lobby
    }
}
challenge icon

Challenge

Easy

Complete the class Order(val item: String, val qty: Int). Its companion object holds the constants MAX_QTY = 10 and PREFIX = "ORD", a private counter for the next order number, the read-only shared total totalItems and the computed count of orders created. The init block requires a quantity between 1 and MAX_QTY with the message quantity must be 1-10 (built from the constant), then gives the order its id ORD-001, ORD-002, ... and adds its quantity to totalItems. label() returns ORD-001 tea x2.

The supplied code prints max per order: 10, then reads lines tea 2 and prints the label or the error message, and finally orders: 2, items: 5. Refused orders do not use up a number.

Your code goes in Order.kt. Main.kt holds the supplied input/output code and cannot be edited.

Try it yourself

fun main() {
    // Supplied input/output code: keep it as it is
    val input = generateSequence(::readLine).toList()
    println("max per order: ${Order.MAX_QTY}")
    for (line in input) {
        val (item, qty) = line.split(" ")
        try {
            println(Order(item, qty.toInt()).label())
        } catch (e: IllegalArgumentException) {
            println(e.message)
        }
    }
    println("orders: ${Order.count}, items: ${Order.totalItems}")
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Kotlin playground