자바에서 예외(Exception)와 오류(Error)는 모두 Throwable 클래스의 하위 클래스라는 공통점이 있습니다. 하지만 두 개념은 발생 원인과 처리 방식에서 매우 중요한 차이를 보입니다.
오류(Error)는 주로 시스템 리소스 부족으로 인해 발생하는 심각한 문제를 의미하며, 애플리케이션 코드에서 직접 처리(catch)해서는 안 되는 문제입니다. 대표적인 예로는 시스템 크래시 오류와 메모리 부족(Out of Memory) 오류가 있습니다. 오류는 대부분 런타임에 발생하기 때문에 비검사(unchecked) 타입에 속합니다.
반면 예외(Exception)는 런타임과 컴파일 타임 모두에서 발생할 수 있는 문제로, 주로 개발자가 작성한 코드에서 비롯됩니다. 예외는 검사 예외(checked exception)와 비검사 예외(unchecked exception) 두 가지 범주로 나뉩니다.
오류(Error) vs 예외(Exception) 비교표
| 번호 | 구분 | 오류(Error) | 예외(Exception) |
|---|---|---|---|
| 1 | 분류 | 비검사(unchecked) 타입으로 분류됨 | 검사(checked)와 비검사(unchecked)로 분류됨 |
| 2 | 패키지 | java.lang.Error에 속함 | java.lang.Exception에 속함 |
| 3 | 복구 가능 여부 | 복구 불가능 | 복구 가능 |
| 4 | 발생 시점 | 컴파일 타임에는 발생하지 않음 | 런타임과 컴파일 타임 모두에서 발생 가능 |
| 5 | 예시 | OutOfMemoryError, IOError | NullPointerException, SQLException |
오류(Error) 발생 예시
아래 코드는 종료 조건 없이 재귀 호출을 무한히 반복하면서 스택 메모리를 모두 소진하여 StackOverflowError가 발생하는 상황을 보여줍니다.
public class ErrorExample {
public static void main(String[] args) {
recursiveMethod(10);
}
public static void recursiveMethod(int i) {
while (i != 0) {
i = i + 1;
recursiveMethod(i);
}
}
}
실행 결과
Exception in thread "main" java.lang.StackOverflowError
at ErrorExample.ErrorExample(Main.java:42)
예외(Exception) 발생 예시
아래 코드는 숫자를 0으로 나누려고 시도하여 ArithmeticException이 발생하는 전형적인 예외 상황입니다.
public class ExceptionExample {
public static void main(String[] args) {
int x = 100;
int y = 0;
int z = x / y;
}
}
실행 결과
java.lang.ArithmeticException: / by zero
at ExceptionExample.main(ExceptionExample.java:7)
정리하면, 오류는 JVM 레벨에서 발생하는 심각한 문제로 복구가 사실상 불가능하며 애플리케이션이 처리하려 해서도 안 됩니다. 반면 예외는 try-catch 블록을 통해 적절히 처리하면 프로그램이 정상적으로 계속 실행될 수 있으므로, 개발 단계에서 예외 상황을 잘 설계하고 관리하는 것이 안정적인 자바 애플리케이션을 만드는 핵심입니다.