이 글은 자바와 코틀린을 비교하면서 코틀린을 공부하던 중 Checked Exception에 대하여 자바와 코틀린의 처리 방식이 다르다는 것을 알게되었고 코틀린의 Checked Exception의 처리 방식에 대한 의문이 생겨 이 글을 작성하게 되었습니다.
우선 저의 의문을 작성하기에 앞서 예외에 관련된 선수지식이 필요하기 때문에 간단히 작성하고 넘어가겠습니다.
각 계층에 대해 간단하게 작성해보겠습니다.
Throwable : 예외 계층의 최상위 클래스
Error : 시스템에 비정상적인 상황 발생, 예측이 어렵고 기본적으로 복구 불가능
Exception : 시스템에서 포착 가능하여(try-catch)복구 가능, 예외 처리 강제
RuntimeException: 런타임시에 발생하는 예외, 예외처리 강제하지 않음
Checked Exception
Unchecked Exception
제 의문은 자바와 코틀린에서의 Checked Exception의 처리에 대해 공부하면서 발생하였습니다. 글로 작성하는 것보다 코드로 이해하는 것이 편할 것 같아서 코드로 보여드리겠습니다. 코드는 패스트캠퍼스의 Kotlin & Spring: 리팩토링부터 서비스구현까지의 강의를 참고하였습니다.
java
위에서 보이는 것과 같이 자바에서의 Checked Exception은 컴파일 에러가 발생하기 때문에 무조건 try-catch로 감싸거나 throws로 예외를 전파해야합니다.
위에서 작성한 코드는 아래와 같이 해결할 수 있을 것입니다.
하지만 대부분의 개발자들은 자바에서 Checked Exception을 처리할 때 의미 없는 처리를 반복하게되고 Checked Exception이 발생할 경우 catch안에서 에러를 해결하는 일은 생각보다 흔하지 않고 오히려 생산성을 감소시킨다고 합니다.
예시는 아래와 같습니다.
java
try {
log.append(message)
} catch(IOException e) {
// Do nothing
}
try {
File file = FileUtils.get(filename);
// ...
} catch (FileNotFoundException e) {
// 파일이 없는데 어떤 처리를 하지?
}
try {
return objectMapper.readValue(json, clazz);
} catch (IOException e) {
// 단순 에러 로그 출력
logger.error(e.getMessage(), e);
}
하지만 아래와 같이 코틀린은 Checked Exception을 강제하지 않습니다.
또 원하는 경우에만 try-catch를 쓸 수 있습니다.
아마 제가 추측하기로는 코틀린은 위에서 언급했던 자바의 단점을 보완하기 위해 Checked Exception을 강제하지 않고, 원하는 경우에만 try-catch를 쓸 수 있게 만들었다고 느꼈습니다.
제 의문은 여기서 발생했습니다.
이 코드에서 무슨 에러가 발생할 수 있다라는 것을 컴파일 시점에 알 수 있는 건 굉장히 좋은 기능 아닌가..? 이게 없어진거잖아?
위에서 작성한 코드를 바탕으로 예시를 작성해보겠습니다.
Thread.sleep(1)
이라는 코드를 작성할 상황이 생겼습니다.Thread.sleep(1)
은 예외가 발생할 수 있다는 것을 알게 되었습니다.Thread.sleep(1)
이라는 코드를 작성할 상황이 생겼습니다.우선 당장 생각나는 것은 테스트가 필수적이라는 생각입니다.
원하는 것만 예외처리 할 수 있다는 것은 생산성에 도움이 되고 의미없는 처리를 줄여준다는 부분에서 굉장히 큰 장점이라고 생각하지만 위에서 언급했던 자바와 같이
"이 코드에서는 이런이런 에러가 발생할 수도 있어"
라는 인지가 되어있는 상태로 코드를 작성했던 것도 큰 장점이라고 생각했었습니다.
하지만 코틀린을 통해 코드를 작성하게 되면 컴파일 단계에서 에러의 발생가능성을 미리 알 수 없기 때문에 다양한 상황을 바탕으로 테스트를 해봐야한다고 느껴졌습니다.
다른 분들에게도 이와 같은 문제에 대해서 어떻게 생각하는지 여쭤보기도 하고 제가 잘못생각했던 부분이 있다면 추가로 작성하도록 하겠습니다.
2022.11.30 일 내용추가
토스 개발자님의 답변
요약하자면
1. checked exception을 활용하여 올바른 에러 핸들링하는 경우가 드뭅니다.
2. 제 생각에도 공감을 해주셨습니다.
3. 모든 것엔 trade off가 있고 checked exception이 큰 역할을 하지 못해서 unchecked exception방향으로 가고 있다고 이해하는게 좋습니다.
제가 잘못이해하고 있거나 잘못 작성한 부분이 있다면 지적, 비판, 피드백 뭐든 해주시면 감사하겠습니다!