Kotlin Require and Check
require and check test a condition and throw an exception when the condition fails. require guards values passed in and check guards the state of an object.
require guards an argument
discount calls require on the percent argument. The failing call lands in the catch block and prints the lazy message.
fun discount(price: Int, percent: Int): Int {
require(percent in 0..100) { "Percent must be between 0 and 100" }
return price - price * percent / 100
}
fun main() {
println(discount(200, 25))
try {
println(discount(200, 140))
} catch (e: IllegalArgumentException) {
println(e.message)
}
}requireNotNull on a nullable argument
requireNotNull hands back the stored name when it is not null. A null name throws IllegalArgumentException with the given message.
fun greet(name: String?): String {
val checked = requireNotNull(name) { "Name is required" }
return "Hello, $checked"
}
fun main() {
println(greet("Ana"))
try {
println(greet(null))
} catch (e: IllegalArgumentException) {
println(e.message)
}
}check guards object state
walkThrough calls check on the open state of the door. The first call fails the test and the later calls pass it.
class Door {
private var open = false
fun openDoor() {
open = true
println("Opened")
}
fun walkThrough() {
check(open) { "Door is closed" }
println("Walked through")
}
}
fun main() {
val door = Door()
try {
door.walkThrough()
} catch (e: IllegalStateException) {
println(e.message)
}
door.openDoor()
door.walkThrough()
}error throws at once
The else branch of the when calls error with a message. That call throws IllegalStateException and the catch block prints its message.
fun roleName(code: Int): String {
return when (code) {
1 -> "Admin"
2 -> "Guest"
else -> error("Unknown code")
}
}
fun main() {
println(roleName(1))
try {
println(roleName(9))
} catch (e: IllegalStateException) {
println(e.message)
}
}Example
class Ticket(val seats: Int) {
private var sold = 0
fun buy(count: Int) {
require(count > 0) { "Count must be positive" }
check(sold + count <= seats) { "Not enough seats" }
sold += count
println(sold)
}
}
fun main() {
val ticket = Ticket(3)
ticket.buy(2)
try {
ticket.buy(0)
} catch (e: IllegalArgumentException) {
println(e.message)
}
try {
ticket.buy(2)
} catch (e: IllegalStateException) {
println(e.message)
}
}Key points
- require throws IllegalArgumentException when its condition is false.
- The block after a require call builds the message only when the test fails.
- requireNotNull returns the value when it is not null and throws when it is null.
- check throws IllegalStateException when its condition is false.
- error throws IllegalStateException with a given message at once.
- A catch block can read the message of each failure with e.message.
In this example, Ticket sells seats with two guards. require rejects a count of zero as a bad argument. check rejects a sale that passes the seat total as a bad state. The first sale passes both guards and prints 2.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Kotlin Playground
Exercise
Which exception type does a failing require call throw?