자바에서 에러, 예외 관련된 클래스들의 계층구조는 위와 같다. Throwable 클래스를 기준으로 Error, Exception 클래스로 나뉘어진다. 왼쪽에 보이는 Error는 말 그대로 에러와 관련된 클래스이다. 그리고 오른쪽에 보이는 Exception도 말 그대로 예외와 관련된 클래스이다. 자바에서는 실행 시(runtime) 발생할 수 있는 프로그램 오류를 에러(error)와 예외(exception) 두 가지로 구분하였다.
에러는 시스템에 비정상적인 상황이 발생했을 경우에 발생한다. 예를 들어 메모리 부족(OutOfMemoryError)이나 스택 오버플로우(StackOverflowError)와 같이 복구할 수 없는 것을 의미한다. 이러한 에러는 개발자가 예측하기도 쉽지 않고 처리할 수 있는 방법도 없다
예외는 프로그램 실행 중에 개발자의 실수로 예기치 않은 상황이 발생했을 때 이다. 예를들어 배열의 범위를 벗어난(ArrayIndexOutOfBoundsException), 값이 null이 참조변수를 참조(NullPointerException), 존재하지 않는 파일의 이름을 입력(FileNotFoundException) 등등이 있다. 이러한 것들은 그냥 보아도 프로그램에 심각한 오류여서 복수할 수 없는 수준은 아니라는 것을 알 수 있다. 이 예외에는 두 가지로 존재한다.
위의 자바 에러 클래스의 계층 구조를 보았을 때 RuntimeException의 하위 클래스들이 Unchecked Exception이라 하고 RuntimeException의 하위 클래스가 아닌 Exception 클래스의 하위 클래스들을 Checked Exception이라 한다.
체크 예외는 RuntimeException의 하위 클래스가 아니면서 Exception클래스의 하위 클래스들이다. 체크 예외의 특징은 반드시 에러 처리를 해야하는 특징(try/catch or throw)을 가지고 있다.
언체크 예외는 RuntimeException의 하위 클래스들을 의미한다. 이것은 체크 예외와는 달리 에러 처리를 강제하지 않는다. 말그대로 실행 중에(runtime) 발생할 수 있는 예외를 의미한다.
언체크 예외는 이러한 것들이 있다. 그냥 보아도 실행 중에 발생할 만한 이름들이다. 그러면 언체크 예외는 예외처리를 강제하지 않는 이유는 무엇일까?
만약 언체크 예외가 에러처리를 강제해야 했다면 아래와 같은 상황이 발생할 것이다.
public class ArrayTest {
public static void main(String[] args) {
try {
int[] list = {1, 2, 3, 4, 5};
System.out.println(list[0]);
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}
단순히 배열을 만들어 배열의 원소를 출력하고자 하는데 try/catch문을 꼭 사용해야 한다. 이러한 RuntimeException은 개발자들의 실수로 발생하는 것들이기 때문에 에러를 강제하지 않는다
컴파일러가 에러처리를 확인하지 않는 RuntimeException 클래스들은 unchecked 예외라고 부르고, 예외처리를 확인하는 Exception 클래스들은 checked 예외라고 부른다.