Kotlinにおける require は、関数や処理が成立するための「前提条件(precondition)」を明示的に検証するための標準関数です。
主に引数の妥当性チェックに使われますが、本質的には 「呼び出し側が守るべき契約」 をコードとして表現する仕組みです。
requireの基本仕様
構文
require(condition)
require(condition) { "エラーメッセージ" }
挙動
condition == true
→ 何も起こらず、処理は継続されるcondition == false
→IllegalArgumentExceptionがスローされる
デフォルトの例外メッセージは "Failed requirement." です。
なぜ IllegalArgumentException なのか
require がスローする例外は常に IllegalArgumentException です。
これは「不正な引数・不正な前提条件で呼び出された」ことを意味します。
つまり require は、
この関数を呼ぶ側が、条件を満たしていない
という責任の所在を例外型によって明確にします。
エラーメッセージをラムダで渡す理由
require(age >= 0) { "age must be >= 0: $age" }
このラムダは 条件が false のときだけ評価されます。
- 成功時はメッセージ生成が行われない
- 文字列補間や重い処理を書いても無駄なコストが発生しない
これは Kotlin 標準ライブラリが require を inline 関数として実装しているためです。
requireの典型的な使用例
数値の範囲チェック
fun withdraw(amount: Int) {
require(amount > 0) { "amount must be positive" }
}
文字列の妥当性チェック
fun registerUser(name: String) {
require(name.isNotBlank()) { "name must not be blank" }
}
複数の前提条件を明示する
fun transfer(from: Account, to: Account, amount: Int) {
require(amount > 0)
require(from != to)
require(from.balance >= amount)
// 本処理
}
このように 関数の冒頭に前提条件をまとめる ことで、関数の仕様そのものがコードから読み取れるようになります。
requireNotNull について
null チェック専用の前提条件
fun printLength(text: String?) {
val value = requireNotNull(text) { "text must not be null" }
println(value.length)
}
- null の場合は
IllegalArgumentException - 戻り値は non-null 型 として扱える
これは Kotlin の Contract(契約) により、「ここ以降は null でない」という情報がコンパイラに伝わるためです。
require・check・assert の違い
Kotlinには目的の異なる検証関数が用意されています。
| 関数 | 役割 | 例外 | 意味 |
|---|---|---|---|
require | 前提条件の検証 | IllegalArgumentException | 呼び出し側の責任 |
check | 状態の検証 | IllegalStateException | 自身(クラス・処理)の責任 |
assert | デバッグ用検証 | AssertionError | 開発時のみ |
check の例(状態の不整合)
class Service {
private var initialized = false
fun init() {
initialized = true
}
fun execute() {
check(initialized) { "Service is not initialized" }
}
}
assert についての注意点
- JVMでは通常 無効
-ea(enable assertions)オプションを付けた場合のみ有効- 本番ロジックの前提条件チェックには向かない
requireを使うべきでないケース
ビジネスロジック上の分岐
// 不適切な例
require(age >= 18)
年齢制限のように 想定される条件分岐 は、例外ではなく通常の制御フローで扱う方が設計として自然です。
ユーザー入力の検証
- フォーム入力
- API リクエストのバリデーション
これらは「起こり得る失敗」であるため、Result や独自の検証結果オブジェクトで扱う方が保守性は高くなります
(ただし、例外を捕捉してレスポンスに変換する設計も一般的です)。
設計上の指針(実務向けまとめ)
- 前提条件(呼び出し側の責任) →
require - 内部状態の整合性 →
check - null を許可しない前提 →
requireNotNull requireは関数の冒頭にまとめる- 仕様をコメントではなくコードで表現する
結論
require は単なる例外スローのショートカットではなく、
- 関数の契約を明示する
- 不正な呼び出しを即座に検出する
- コード自体を仕様書にする
ための Kotlin らしい設計ツールです。
正しく使えば、バグの早期発見と可読性の向上を同時に実現できます。
以上、Kotlinのrequireについてでした。
最後までお読みいただき、ありがとうございました。










