Java Checked Exception과 Unchecked Exception 차이 이해하기
Java의 예외(Exception)은 크게 두 가지로 나루 수 있습니다. 바로 Checked Exception과 Unchecked Exception입니다. 예외 처리나 트랜잭션 처리 같은 기능을 구현할 때 꼭 알아야 하는 중요한 개념이지만 기초 공부를 충분히 하지 않았다면 정확히 이해하지 못하고 넘어가기 쉬운 부분입니다. 최대한 쉽게 설명해보겠습니다.
Exception의 상속 구조
Object
└── Throwable
├── Error (Unchecked)
└── Exception (Checked and Unchecked)
├── RuntimeException (Unchecked)
└── Other Exceptions (Checked)
- 모든 예외의 최상위 클래스는 Throwable이고, Throwable을 상속하는 Exception은 Checked와 Unchecked를 모두 포함합니다.
- Checked Exception 중 하나인 SQLException을 보면 Exception을 상속 받고 있는 걸 알 수 있습니다.
public class SQLException extends java.lang.Exception
implements Iterable<Throwable>
- Unchecked Exception 중 하나인 NullPointerException을 보면 RuntimeException을 상속 받고 있는 걸 알 수 있습니다.
public class NullPointerException extends RuntimeException
💡 IntelliJ에서 Ctrl + Shift + N으로 예외 클래스 이름을 검색해보면 해당 예외가 어떤 클래스를 상속받는지 직접 확인할 수 있습니다.
Checked Exception이란?
Checked Exception은 컴파일 시점에 반드시 예외 처리를 해야 하는 예외입니다. 예외 처리를 하지 않으면 컴파일 자체가 불가능합니다. 리소스 접근이나 파일 I/O 등과 같이 미리 예측 가능한 오류가 여기에 해당됩니다.
![]() |
컴파일 시 예외 처리가 강제 |
대표적인 Checked Exception
- IOException
- SQLException
- ClassNotFoundException
- InstantiationException
- IllegalAccessException
- NoSuchFieldException
- InterruptedException
예외 처리 방법
- try-catch로 감싸기
- throws로 상위 메소드로 예외 던지기
Unchecked Exception이란?
Unchecked Exception은 프로그램 실행 중에 발생하는 예외입니다. 예외 처리가 필수는 아니며, 컴파일 에러도 발생하지 않습니다.
하지만 예외가 발생하면 프로그램이 그대로 종료되기 때문에, 상황에 따라 적절히 예외 처리를 해주는 것이 좋습니다.
주로 개발자의 실수로 발생하는 오류입니다. (수를 0으로 나누려고 한다거나 형변환이 불가능한 상황인데 형변환을 시도한다거나...)
![]() |
예외 처리를 하지 않아도 실행은 되지만 예외가 발생하면 프로그램이 그 즉시 종료 |
대표적인 Unchecked Exception
- NullPointerException
- ArrayIndexOutOfBoundsException
- IndexOutOfBoundsException
- ClassCastException
- IllegalArgumentException
- ArithmeticException
Checked Exception의 예외 처리가 컴파일 시점에 강제되는 이유
예외 발생 가능성이 있음을 프로그램 실행 전에 예측 가능하기 때문에 당연히 해당 상황이 발생했을 경우를 대비해 놓아야 합니다. (재시도를 한다거나 에러 메시지를 넘겨준다거나...)
그리고 Java의 철학 중에 하나가 "컴파일러가 잡을 수 있는 문제는 최대한 컴파일 시점에 잡자"라고 하네요. C나 C++같은 경우에는 모든 예외가 Unchecked 형식이라고 하니 Checked Exception은 Java의 장점 중에 하나로 봐도 될 것 같습니다.
Unchecked Exception의 예외 처리가 강제되지 않는 이유
Unchecked Exception이 발생하는 근본적인 이유는 프로그램 로직 자체를 잘못 만들었기 때문입니다.
// 예시 1: Null 참조
String name = null;
System.out.println(name.length()); // NullPointerException
// 예시 2: 잘못된 인수
List<String> list = new ArrayList<>();
list.get(5); // IndexOutOfBoundsException
Null 체크를 하거나 List의 size를 체크하면 발생할 일이 없습니다. 이런 것들까지 모두 try-catch나 throws로 감싸야 한다면 거의 모든 코드들을 예 처리해야 합니다. 너무 과하죠.
마무리하며
제 생각에는 이 정도만 알면 충분할 것 같습니다. 저도 Java 공부를 기초부터 꼼꼼하게 하지 않아서 Checked Exception과 Unchecked Exception의 존재를 한참 몰랐었습니다.
언제 처음 인지했었냐면 @Transactional 어노테이션을 단 메소드 안에서 Exception이 발생했을 때 Unchecked Exception만 rollback을 한다는 글을 봤을 때입니다. Checked Exception이 발생 가능한 상황이면 IDE에서 빨갛게 표시해주면서 컴파일 자체가 되지 않지만 이게 Checked Exception인지 Unchecked Exception인지는 따로 공부하기 전에는 잘 모를 것 같습니다.
너무 기본적인 내용인데 기초 공부를 게을리 한 저는 개발자 생활 시작하고 한참이 지나서 알게 됐던 개념이라서 글로 한 번 정리해봤습니다.
댓글
댓글 쓰기