Exception classes
코틀린의 모든 예외 클래스는 Throwable 클래스를 상속받는다. 메시지, 스택 추적, 선택적 원인이 있다.
예외 객체를 throw하려면 throw 표현식을 사용한다.
예외 처리를 하기 위해서는 try-catch 표현식을 사용한다.
try {
// some code
} catch (e: SomeException) {
// handler
} finally {
// optional finally block
}
catch 블록은 0개 이상 존재할 수 있고, finally 블록은 생략할 수 있다. 단, 적어도 하나의 catch 또는 finally 블록이 필요하다.
Try is an expression
try는 반환 값을 가질 수 있는 표현식이다. try 표현식의 반환 값은 try 블록의 마지막 표현식이거나 catch 블록의 마지막 표현식이다. finally 블록의 내용은 표현식의 결과에 영향을 주지 않는다.
val a: Int? = try { input.toInt() } catch (e: NumberFormatException) { null }
Checked exceptions
코틀린은 확인된 예외에 대한 처리를 강요하지 않는다.
Appendable append(CharSequence csq) throws IOException;
위 예시는 StringBuilder 클래스에 의해 구현된 JDK 예제 인터페이스 이다. 이 정의는 구현이 IO작업을 수행할 수 있기 때문에 문자열을 무언가(StringBuilder, 일종의 로그, 콘솔 등)에 추가할 때마다 IOExeption을 잡아야한다고 알려주고 있다. 그런데, 코틀린에서는 IOEception에 대한 catch 블록을 작성하지 않아도 컴파일에 문제는 없다.
try {
log.append(message)
} catch (IOException e) {
// Must be safe
}
자바에서는 대체로 확인된 예외를 처리하기 위해 위와 같이 코드를 작성하곤 하는데, 코틀린은 이러한 형태의 코드를 작성할 필요가 없게끔 catch 블록을 작성하지 않아도 컴파일에 문제가 없도록 했다.
The Nothing type
코틀린에서 throw는 표현식이므로 Elvis 표현식의 일부로 사용할 수 있다.
val s = person.name ?: throw IllegalArgumentException("Name required")
throw 표현식의 유형은 Nothing이다. 이 유형에는 값이 없고, 도달할 수 없는 코드 위치를 표시하는 데 사용된다. 코드에서 nothing 타입을 사용하여 반환되지 않는 함수를 표시할 수도 있다. 이 함수를 호출하면, 컴파일러는 호출 이후에 실행이 계속 되지 않는다는 것을 알게 된다.
fun fail(message: String): Nothing {
throw IllegalArgumentException(message)
}
val s = person.name ?: fail("Name required")
println(s) // 's' is known to be initialized at this point
/*
* s가 null 인 경우 엘비스 식의 우측이 Nothing 타입이 아닌 경우,
* 컴파일 에러가 발생한다.
* 현시점에는 s가 초기화 되어있다고 알려져있다.
*/
Type 추론을 처리할 때도 Nothing 유형을 만날 수 있다. 이 유형의 nullable 변형인 Nothing?에는 null이라는 하나의 가능한 값이 존재한다. null을 사용하여 Type 추론되는 변수를 초기화하고 컴파일러가 구체적인 타입을 결정하는 데 사용할 수 있는 다른 가능한 정보가 없는 경우 컴파일러는 Nothing?으로 추론한다.
val x = null // 'x' has type `Nothing?`
val l = listOf(null) // 'l' has type `List<Nothing?>