What is the difference between require(...) and check(...) in the Kotlin standard library, and which exception does each throw?
answer
- require = argument = IllegalArgumentException
- check = state = IllegalStateException
- Lazy message lambda runs only on failure
- Both inline, both always active
- error(msg) = throw IllegalStateException
basics
~10 sBoth check a condition and throw if it is false. require is for bad arguments and throws IllegalArgumentException. check is for a bad object state and throws IllegalStateException.
solid answer
~40 sBoth are inline stdlib guard functions taking a Boolean. require(value) throws IllegalArgumentException when value is false; use it to validate function arguments at the start of a function. check(value) throws IllegalStateException when false; use it to assert that the object or program is in a valid state to proceed. Semantically: require blames the caller (bad input), check blames the current state. Both have an overload taking a lazy message lambda, require(value) { "msg" }, evaluated only on failure. requireNotNull and checkNotNull are the null-checking variants that also smart-cast the value to non-null. Neither is disabled in production (unlike assert). error(msg) is a shorthand that always throws IllegalStateException.
code
kotlin · 4 linesfun transfer(amount: Int, accountOpen: Boolean) {
require(amount > 0) { "amount must be > 0, was $amount" } // IllegalArgumentException
check(accountOpen) { "account must be open" } // IllegalStateException
}go deeper
Knows require throws IllegalArgumentException for bad args and check throws IllegalStateException for bad state.
Articulates the caller-vs-state intent and mentions the lazy message overload and that both are always active.
Explains inlining (no lambda allocation), how exception type guides catch sites, and pairs the NotNull variants with smart-casting.
Frames precondition choice as part of API contract design and error taxonomy, and how it interacts with global exception handling and observability.
## What these functions are Kotlin's standard library (in `kotlin.Preconditions.kt`) provides small `inline` guard functions that throw when a condition is violated. They make intent explicit and produce clear exceptions. ## require — validate arguments `require(condition)` throws `IllegalArgumentException` if `condition` is `false`. Use it for argument validation: the failure means the **caller** passed something invalid. ```kotlin fun withdraw(amount: Int) { require(amount > 0) { "amount must be positive, was $amount" } // ... } ``` `IllegalArgumentException` semantically signals "a method has been passed an illegal argument." ## check — validate state `check(condition)` throws `IllegalStateException` if `condition` is `false`. Use it when the **object's or program's state** is wrong for the operation, regardless of arguments. ```kotlin class Connection { private var open = false fun send(data: String) { check(open) { "connection is not open" } // ... } } ``` ## Choosing between them - `require` -> the **input** is bad -> `IllegalArgumentException`. - `check` -> the **state** is bad -> `IllegalStateException`. This distinction matters because callers may catch these exceptions differently, and the type documents whose fault the failure is. ## Lazy message and inlining Both take an optional `message: () -> Any` lambda evaluated **only on failure**, so building an expensive message string costs nothing on the happy path. Because the functions are `inline`, no lambda object is allocated. ## Not the same as assert Unlike `assert`, `require` and `check` are **always active** in production — they are normal exceptions, not toggled by a JVM flag.
- Are require and check disabled in release builds like assert can be?No. They are ordinary functions that always throw; only assert is gated by the -ea / -enableassertions JVM flag.
- Why use require instead of writing if (x) throw IllegalArgumentException(...)?It is shorter, communicates intent, gives a consistent exception type and message format, and (for the NotNull variants) smart-casts the value.
require checks the ticket you were handed (caller's fault); check confirms the gate is actually open (the system's state).
saying these in an interview costs you the question
- Saying require throws IllegalStateException (it throws IllegalArgumentException)
- Claiming require/check are stripped out in production
- Using check for argument validation or require for state
- Thinking the message is always evaluated even on success
- Confusing them with assert