require() / check() / error()
Kotlin's require(), check(), and error() are standard functions for validating preconditions and state. They throw an exception when a condition is not met, making the intent of your code explicit.
Syntax
// Validate argument preconditions (IllegalArgumentException)
require(condition) { "Error message" }
requireNotNull(value) { "Message when value is null" }
// Validate state preconditions (IllegalStateException)
check(condition) { "Error message" }
checkNotNull(value) { "Message when value is null" }
// Always throws an exception (IllegalStateException)
error("Error message")
Function Reference
| Function | Exception thrown | Description |
|---|---|---|
| require(cond) { msg } | IllegalArgumentException | Validates an argument. Throws if the condition is false. |
| requireNotNull(v) { msg } | IllegalArgumentException | Throws if the argument is null. Returns a non-null value. |
| check(cond) { msg } | IllegalStateException | Validates state. Throws if the condition is false. |
| checkNotNull(v) { msg } | IllegalStateException | Throws if the state is null. Returns a non-null value. |
| error(msg) | IllegalStateException | Always throws an exception. Used for unreachable code paths. |
Sample Code
class BankAccount(initialBalance: Double) {
private var balance: Double = initialBalance
private var isOpen: Boolean = true
init {
// Validate constructor argument
require(initialBalance >= 0) { "Initial balance must be 0 or greater (got: $initialBalance)" }
}
fun deposit(amount: Double) {
require(amount > 0) { "Deposit amount must be greater than 0" }
check(isOpen) { "The account is already closed" }
balance += amount
println("Deposited: $amount → Balance: $balance")
}
fun close() {
isOpen = false
}
}
fun processInput(input: String?) {
// Use requireNotNull to get a non-null value.
val value = requireNotNull(input) { "Input cannot be null" }
println("Processing: $value") // value is String (non-null)
}
fun getDayName(day: Int): String = when (day) {
1 -> "Monday"
2 -> "Tuesday"
// ...
else -> error("Invalid day: $day") // Should never be reached
}
fun main() {
val account = BankAccount(1000.0)
account.deposit(500.0) // Deposited: 500.0 → Balance: 1500.0
try {
account.deposit(-100.0) // IllegalArgumentException
} catch (e: IllegalArgumentException) {
println("Argument error: ${e.message}")
}
account.close()
try {
account.deposit(100.0) // IllegalStateException
} catch (e: IllegalStateException) {
println("State error: ${e.message}")
}
processInput("Hello") // Processing: Hello
println(getDayName(1)) // Monday
try {
println(getDayName(8)) // IllegalStateException
} catch (e: IllegalStateException) {
println("Error: ${e.message}")
}
}
Notes
The common convention is to use require() for argument validation (at the entry point of a function) and check() for state validation (to verify that an object is in a valid state).
Because the message is evaluated lazily via a lambda, the string is not constructed when the condition is true, making this approach efficient.
For exception handling with try-catch, see try / catch / finally.
If you find any errors or copyright issues, please contact us.