어 나 갱수.

[Java] Java Exception 정리 본문

Java

[Java] Java Exception 정리

김경수 2024. 8. 22. 11:27
728x90

Java의 Exception 예외처리에 대해 알아보기 이전에 Error(에러)와 Exceptin(예외)에 대해 정리해보겠습니다.

 

Error(에러)와 Exception(예외)

Error는 시스템에서 문제가 생겼을 때 발생하는 것을 말합니다. 이는 시스템 레벨에서 발생하는 것을 뜻하며 심각한 오류로 판단합니다.
개발자가 미리 에러를 예측해서 처리하는 것이 쉽지 않기 때문에, 개발자가 에러에 대해 미리 처리에 대해 신경 쓸 필요는 없습니다.

 

Exception은 개발자가 짠 비즈니스 로직에서 문제가 생겼을 때 발생하는 것을 말합니다. 시스템 레벨에서 발생하는 것이 아니기 때문에 개발자가 로직을 짜면서 미리 예외를 예측하여 처리할 수 있습니다. 개발자가 처리할 수 있기 때문에 구분하고 그에 따른 처리 로직을 잘 구현하는 것이 중요합니다.

 

예외 클래스

 

모든 예외 클래스들은 Throwable의 상속을 받고 있습니다. Throwable의 상속을 받고 있는 Error와 Exception 이 있습니다.

Error는 다시 정리하자면 시스템의 문제가 생겨서 발생하는 것 이기 때문에 개발자가 로직을 구현하면서 미리 예측하고 그에 대해 어떻게 처리할지 예측하는 거는 어렵고 굳이 할 필요는 없습니다. Exception은 개발자가 짠 로직 레벨에서 발생하는 문제이기 때문에 개발자가 충분히 비즈니스 로직을 짜면서 어떤 부분에서 문제가 발생할지 미리 예측하고 그에 대해 처리할 수 있는 로직도 추가할 수 있습니다.

 

Error의 자식들을 보면 OutOfMemoryError, StackOverFlowError, LinkageError와 같이 개발자가 로직을 통해서 처리하기 힘든 에러들입니다. 

StackOverflowError : 호출의 깊이가 깊어지거나 재귀가 지속되어 stack overflow 가 생기게 되는 오류입니다.

OutOfMemoryError : JVM이 할당한 메모리의 부족으로 더 이상의 객체를 할당할 수 없는 경우 발생하는 오류입니다.

 

Exception의 자식들을 보면 RuntimeException을 볼 수 있습니다. RuntimeException을 통해 CheckedException, UncheckedException을 구분하기 때문에 굉장히 중요한 개념으로 볼 수 있습니다. Exception의 자식 클래스중에 RuntimeException을 제외한 나머지 모든 예외 클래스들은 CheckedException입니다. RuntimeException를 포함한 그의 자식 클래스 모두 UncheckedException이라고 부릅니다. 

CheckedException , UncheckedException

CheckedException과 UncheckedException을 구분하는 가장 좋은 방법은 '꼭 처리를 해야 되는가'라고 생각합니다.

CheckedException이 로직에서 발생한다면 반드시 try-catch 문이나 다른 방법 등을 통해서 그 에러에 대해서 꼭 처리를 해야 합니다.

그렇지 않으면 프로그램 자체가 컴파일이 되지 않습니다. 반면에 UncheckedException은 꼭 예외처리를 해야 하는 것은 아닙니다.

이 UncheckedException은 대부분 개발자의 부주의를 통해서 발생합니다. 이 에러들은 우리가 프로젝트를 실행할 때는 전혀 문제가 없습니다. 그래서 굳이 에러가 발생할 상황이 만들어지지 않는다면 운이 좋아 넘어갈 수 있는 에러입니다. 그렇기 때문에 모두 체크할 필요가 없습니다. 이러한 에러를 UncheckedException이라고 부릅니다.

 

CheckedException은 컴파일 시점에서 발생합니다. 그렇기 때문에 컴파일을 돌리면 명확하게 문제에 대해 알 수 있습니다. 그래서 이름이 CheckedException입니다. 그러나 컴파일 단계에서 확인할 수 없는 예외인 UncheckedException은 프로그램이 실행되고 실행하면서 파악할 수 있는 에러입니다. 실행되는 도중에 발생하는 에러여서 RuntimeException이라고도 부릅니다.

 

CheckedException에 대한 예시를 들어보면 IO Exception이 있습니다.

위에서 발생하는 빨간 줄을 통해 에러를 확인하면 Unhandled exception: java.io.IOException이라는 에러가 발생합니다.

위와 같이 try-catch문으로 IO Exception에 대한 예외처리를 해주면 에러가 사라지는 것을 볼 수 있습니다.

위처럼 컴파일 과정에서 에러를 캐치해 줘서 컴파일에 실패하게 해주는 에러들을 CheckedException이라고 부릅니다. 저 에러들에 대한 예외처리를 해주지 않는다면 컴파일에 실패하기 때문에 반드시 체크하는 과정이 필요합니다.

 

UncheckedException을 더 자세히 설명해 보자면 대표적인 UncheckedException로는 IndexOutOfBoundsException이 있습니다. IndexOutOfBoundsException는 정해진 리스트 범위를 벗어난 인덱스를 사용할 경우 발생하는 예외입니다. 이러한 예외는 개발자가 로직을 잘못 짰을 때 발생하는 에러로 UncheckedException이라고 부릅니다. 또한 이 에러는 실행시점에서 리스트의 인덱스를 사용해서 어떠한 요청을 했을 때 발생하는 에러로 RuntimeException을 상속받습니다. 

 

RuntimeExcpetion을 상속받는 대표적인 Exception

  • IllegalArgumentException
  • IndexOutOfBoundException
  • NullPointerException
  • SecurityException

어떤 예외를 더 중시해야 하나요

개발자가 개발을 하면서 그러면 어떤 예외를 처리하는데 더 집중해야 할까요? 제가 생각했을 때는 UncheckedException이라고 생각합니다. CheckedException은 개발을 하면서 하는 컴파일 과정에서 충분히 에러를 찾고 해결할 수 있는 에러들입니다. 그러나 UncheckedException은 개발 과정에서 비즈니스 로직에서 충분히 예외 처리를 하면서 테스트를 완벽하게 하지 않으면 서비스를 사용하는 고객에게 큰 영향을 끼칠 가능성이 높습니다.

728x90