throw exceptions with precondition functions

Precondition functionUse caseException thrown
require()Checks user input validityIllegalArgumentException
check()Checks object or variable state validityIllegalStateException
error()Indicates an illegal state or conditionIllegalStateException

1. require()

  • 함수의 매개변수(Argument)가 유효한지 검증할 때 사용
fun setAge(age: Int) {
    // age가 0보다 커야 한다는 조건을 검증
    require(age > 0) { "나이는 0보다 커야 합니다. 입력된 값: $age" }
    
    println("나이가 $age세로 설정되었습니다.")
}
 
// 실행 예시
// setAge(-5) // IllegalArgumentException 발생

2. check()

  • 객체의 상태(State)가 특정 로직을 수행하기에 적절한지 검증할 때 사용
class Printer {
    var isInitialized = false
 
    fun printDocument(text: String) {
        // 프린터가 초기화된 상태인지 검증
        check(isInitialized) { "프린터가 초기화되지 않았습니다. 먼저 setup()을 호출하세요." }
        
        println("출력 중: $text")
    }
 
    fun setup() {
        isInitialized = true
    }
}
 
// 실행 예시
// val printer = Printer()
// printer.printDocument("Hello") // IllegalStateException 발생

3. error()

  • 정상적인 제어 흐름상 도달해서는 안 되는 지점이나, 명백히 잘못된 상태에 진입했을 때 강제로 예외를 발생시키기 위해 사용
fun getUserRole(level: Int): String {
    return when (level) {
        1 -> "Admin"
        2 -> "User"
        else -> error("정의되지 않은 레벨입니다: $level") // 논리적으로 발생하면 안 되는 상황
    }
}
 
// 실행 예시
// getUserRole(99) // IllegalStateException 발생

중요한 예외

  • IllegalArgumentException

    • 인수의 값이 잘못된 경우.
      • 사용자가 값을 잘못 입력한 경우에 발생하는 예외
      • 사용자의 잘못으로 발생하는 예외를 대표함.
  • IllegalStateException

    • 소스코드가 값을 처리할 준비가 안된 경우에 발생하는 예외

예외의 계층 구조

Java 와의 가장 큰 차이점 : checked exception 이 존재하지 않음.

  • Error

    • 회복이 불가능한 오류.
      • 예시 OutOfMemeoryError
    • catch 블록에서 잡을 수 없음.
  • Exception

    • 회복이 가능한 오류
      • 대부분. 커스텀 에러 만들 때도 Exception 을 상속하여 만들어야 함.