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 playersConstants 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
2Top 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
EasyComplete 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}")
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesPrimary Constructorsinit Blocks and ValidationSecondary ConstructorsRecap - Library Card4Inheritance
Open Classes and SubclassesOverriding Memberssuper and ConstructorsAbstract ClassesRecap - Staff Directory2Properties and Encapsulation
Custom AccessorsVisibility ModifiersPrivate Setterslazy and lateinitRecap - Bank Account5Interfaces
Declaring InterfacesDefault MethodsMultiple InterfacesInterfaces as TypesRecap - Payment Methods8Generics
Generic FunctionsGeneric ClassesType ConstraintsVariance With in and outRecap - Priority Queue11Project: Library Management
Books and MembersBorrowing Books3Objects and Companions
Object DeclarationsCompanion ObjectsConstants With constObject ExpressionsRecap - Ticket OfficePractice on your own: Kotlin playground