이러한 두 가지는 ⚡중요한 차이점 존재
-> 많은 개발자가 예외가 전파되는 과정을 제대로 추적 못함
-> 코틀린의 모든 예외는 unchecked 예외임. 따라서 예외를 처리하지 않을 수도 있음
- 사용자가 반드시 처리하게 강제되는 예외를 checked 예외라고 부르고,
- 처리하지 않아도 실행에 문제가 없는 예외를 unchecked 예외라고 부름
- 예외는 예외적인 상황을 처리하기 위해서 만들어졌으므로 명시적인 테스트만큼 빠르게 동작❌
- try-catch 블록 내부에 코드를 배치하면, 컴파일러가 할 수 있는 최적화가 제한
예측 가능 범위의 오류 -> null 과 Failure
예측 불가능 범위의 오류 -> throw
ex)
inline fun <reified T> String.readObjectOrNull(): T? { //... if(incorrectSign) { return null } //... return result } inline fun <reified T> String.readObject(): Result<T> { //... if(incorrectSign) { return Failure(JsonParsingException()) } //... return Success(result) } sealed class Result<out T> class Success<out T>(val result: T): Result<T>() class Failure<val throwable: Throwable): Result<Nothing>() class JsonParsingException: Exception()
↪ 이렇게 표시되는 오류는 다루시 쉬우며 놓치기 어려움
null을 처리해야 한다면, 안전 호출(safe call) or Elvis 연산자 같은 다양한
널 안정성 기능을 활용 !
val person = userText.readObjectOrNull<Person>() val age = when(person) { is Success -> person.age is Failure -> -1 }
↪ try-catch보다 효율적, 쉽고 명확함
sealed result : 추가적인 정보를 전달해야 할 때
null : 일반적
Failure : 처리할 때 필요한 정보를 가질 수 있음
일반적으로 두 가지 형태의 함수를 사용
하나는 예상 가능, 다른 하나는 예상 불가능
get : 특정 위치에 있는 요소를 추출할 때 사용
-> 해당 위치에 없다면 IndexOutOfBoundException 발생
getOrNull : 오류가 발생할 수 있는 경우에 사용
-> 오류 발생 시 null return
이외에도 getOrDefault 같은 선택지 존재
하지만 getOrNull or Elvis 연산자(?:)가 더 쉬움👍
⭐
개발자는 항상 자신이 안전하게 추출할 거라고 생각
따라서 nullable 리턴 ❌ !!!
개발자에게 null이 발생할 수 있다는 경고를 주려면,
-> getOrNull 등과 같은 예측가능한 리턴 사용 !!