개발을 하다 보면 "이 함수에는 절대 음수가 들어오면 안 돼", "이 시점에는 반드시 초기화가 되어 있어야 해" 같은 필수 조건들이 생깁니다.
이런 조건들을 처리할 때, 매번 if (x < 0) throw Exception(...)을 쓰고 계셨나요? 코틀린에서는 이런 '방어적 프로그래밍Defensive Programming)'을 위해 아주 멋진 표준 함수들을 제공합니다. 바로 require, check, assert 입니다.
1. 인자값 검증의 정석: require()
함수를 호출할 때 넘겨받은 파라미터(Argument)가 유효한지 검사할 때 사용합니다. 조건이 맞지 않으면 IllegalArgumentException 을 발생시킵니다.
- 용도: 호출자가 값을 잘못 줬다고 알릴 때
- 위치: 보통 함수의 맨 윗줄.
fun setAge(age: Int) {
// [Before] if문 사용
if (age < 0) {
throw IllegalArgumentException("나이는 0보다 커야 합니다.")
// [After] require 사용 ✨
require(age >= 0) { "나이는 0보다 커야 합니다. 입력된 값: $age" }
println("나이 설정 완료: $age")
}
장점:
1. 코드가 훨씬 간결해집니다.
2. 이 함수가 어떤 값을 필요로 하는지 명확하게 보여줍니다(문서화 효과).
3. 스마트 캐스팅(Smart Casting)을 도와줍니다. (null 체크 등)
2. 상태 검증의 정석: check()
파라미터는 정상인데, 현재 객체의 상태(State)가 작업을 수행하기에 적절하지 않을 때 사용합니다.
조건이 맞지 않으면 IllegalStateException을 발생시킵니다.
- 용도: 해당 작업을 할 수 있는 상태가 아닐 때
- 예시: 초기화가 안 됐는데 사용하려 할 때, 로그인이 안 됐는데 글을 쓰려 할 때.
class Car {
var isEngineOn = false
fun accelerate() {
// 시동이 켜져 있어야만 가속 가능
check(isEngineOn) { "시동을 먼저 켜주세요." }
println("부웅~ 속도를 올립니다.")
}
}
3. 치명적인 오류: error()
로직상 절대 도달해서는 안 되는 코드에 도달했을 때, 강제로 에러를 발생시킵니다.
val input = "UNKNOWN"
val result = when(input) {
"A" -> 1
"B" -> 2
else -> error("예상치 못한 입력값입니다!") // IllegalStateException 발생
}
4. null 검증: requireNotNull, checkNotNull
변수가 null인지 아닌지 검사하고, null이 아니면 그 값을 반환해 줍니다.
fun printName(name: String?) {
// name이 null이면 Exception 발생, 아니면 non-null 타입으로 변환
val validName = requireNotNull(name) { "이름은 필수입니다." }
// 여기서부터 validName은 String? 이 아니라 String 타입입니다.
println(validName.length)
}
5. 테스트 코드에서의 assert()
assert()는 앞선 함수들과 다르게, JVM의 -ea (Enable Assertions) 옵션이 켜져 있을 때만 동작합니다. 주로 테스트나 디버깅 목적의 내부 검증용으로 사용됩니다. 실제 배포(Production) 환경에서는 무시됩니다.
fun calculate(a: Int, b: Int): Int {
val result = a + b
// 배포 시에는 검사하지 않음 (성능 영향 X)
assert(result > 0) { "결과는 양수여야 함" }
return result
}
정리: 무엇을 써야 할까?
| 함수 | 발생하는 예외 | 언제 사용하는가? |
| require | IllegalArgumentException | 인자값이 올바른지 검사할 때 (가장 많이 씀) |
| check | IllegalStateException | 현재 상태가 올바른지 검사할 때 |
| error | IllegalStateException | 절대 오면 안 되는 곳에 왔을 때 |
| assert | AssertionError | 개발 단계에서 내부 로직을 검증할 때 |
코틀린의 이런 함수들을 적극적으로 사용하면, 에러를 조기에 발견하고(Fail Fast) 더 견고한 애플리케이션을 만들 수 있습니다. 지금 바로 if-throw 코드를 require로 바꿔보세요!
'Dev Log > Kotlin' 카테고리의 다른 글
| [Kotlin] 예외 처리 패턴: 사용자 입력을 '우아하게' 다시 받는 법 (ft. 재귀 함수) (0) | 2026.01.02 |
|---|---|
| [Kotlin/Test] 테스트 코드 작성을 위한 JUnit5와 AssertJ 문법 총정리 (TDD 기초) (0) | 2026.01.02 |
| [Kotlin] 코틀린 문자열 자르기와 다루기 완전 정복 (split, substring, 정규식) (0) | 2026.01.02 |
| [우테코 AN 8기] 프리코스 | 클린 코드란 무엇일까? (ex. Kotlin) (0) | 2025.10.18 |
| [우테코 AN 8기] 프리코스 1주차 과정을 진행하며.. | 깃허브 커밋 메시지, 코틀린 컨벤션 (0) | 2025.10.14 |