728x90

자바 프로그래밍에서 '예외 처리'는 단순히 에러를 막는 기술이 아닙니다. 이는 프로그램의 신뢰성을 결정짓는 설계의 영역입니다. 자바는 모든 예외와 에러를 객체로 취급하며, 이를 체계적인 계층 구조(Hierarchy)로 관리합니다. 이 구조를 정확히 이해해야만 '언제 예외를 던지고(throw)', '어디서 잡을지(catch)'에 대한 전문적인 판단이 가능해집니다.
1. 모든 것의 시작: Throwable 클래스
자바 예외 계층의 최상위에는 java.lang.Throwable 클래스가 존재합니다. 모든 예외 객체는 이 클래스를 상속받아야 하며, 크게 Error(에러)와 Exception(예외) 두 갈래로 나뉩니다.
- Error: 시스템 레벨의 심각한 문제입니다. JVM 자체의 결함이나 리소스 부족(OutOfMemoryError, StackOverflowError) 등이 해당하며, 애플리케이션 코드 수준에서 복구할 수 없는 상황을 의미합니다.
- Exception: 프로그램 코드 내에서 수습 가능한 문제입니다. 개발자는 이 Exception 계층을 적절히 핸들링하여 프로그램이 갑자기 종료되는 것을 막아야 합니다.
2. Exception의 두 얼굴: Checked vs Unchecked
Exception 클래스의 하위 계층은 다시 Checked Exception과 Unchecked Exception으로 구분됩니다. 이 둘을 구분하는 기준은 바로 RuntimeException의 상속 여부입니다.
| 비교 항목 | Checked Exception | Unchecked Exception (Runtime) |
|---|---|---|
| 상속 관계 | Exception 상속 (RuntimeException 제외) | RuntimeException 상속 |
| 처리 시점 | 컴파일 단계에서 확인 | 실행(Runtime) 단계에서 확인 |
| 처리 강제성 | 반드시 try-catch 또는 throws 필요 | 명시적인 예외 처리를 강제하지 않음 |
| 대표 사례 | IOException, SQLException, ClassNotFoundException | NullPointerException, IndexOutOfBoundsException |
| 발생 원인 | 외부 환경(파일, DB, 네트워크) 영향 | 개발자의 논리적 오류 (프로그래밍 실수) |
3. 실전 코드 예제 (Sample Example)
두 예외의 차이를 코드를 통해 확인해 보겠습니다.
Case A: Checked Exception (처리가 강제됨)
import java.io.FileReader;
import java.io.IOException;
public class CheckedExample {
public void readFile() {
// 파일을 읽는 시도 자체가 컴파일 에러를 유발 (IOException 처리 필요)
try {
FileReader fr = new FileReader("test.txt");
} catch (IOException e) {
System.err.println("파일을 찾을 수 없거나 읽을 수 없습니다.");
}
}
}
Case B: Unchecked Exception (개발자 주의 필요)
public class UncheckedExample {
public void divide() {
int a = 10;
int b = 0;
// 컴파일러는 경고하지 않지만, 실행 시 ArithmeticException 발생
// 방어 코드를 통해 예방하는 것이 정석입니다.
if (b != 0) {
System.out.println(a / b);
} else {
System.out.println("0으로 나눌 수 없습니다.");
}
}
}
4. 전문가의 조언: 예외 설계의 골든 룰
전문 개발자는 예외를 단순히 '에러 방지'용으로 쓰지 않습니다. 다음과 같은 원칙을 지키는 것이 중요합니다.
- 예외를 무시하지 마세요: 빈 catch 블록은 버그를 숨기는 가장 위험한 행위입니다. 최소한 로그라도 남겨야 합니다.
- 구체적인 예외를 잡으세요:
catch (Exception e)보다는catch (FileNotFoundException e)와 같이 구체적인 예외를 명시하는 것이 디버깅에 유리합니다. - 복구 가능 여부를 판단하세요: 호출자가 예외 상황을 복구할 수 있다고 판단되면 Checked Exception을, 그렇지 않다면 Unchecked Exception을 던지는 것이 객체 지향적인 설계입니다.
5. 결론
자바의 예외 계층 구조는 프로그램의 안전망입니다. 최상위 Throwable부터 RuntimeException에 이르기까지, 각 클래스의 존재 이유를 파악하고 적절한 처리를 생활화하는 것이 시니어 개발자로 가는 첫걸음입니다.
출처 및 참고문헌
- Java SE 17 Specification: Chapter 11. Exceptions
- Effective Java 3rd Edition (Joshua Bloch) - Item 70, 71, 72
- Oracle Java Tutorials: The Catch or Specify Requirement
728x90
'Language > Java' 카테고리의 다른 글
| [JAVA] finally 블록이 실행되지 않는 예외적인 4가지 시나리오 분석 (0) | 2026.01.20 |
|---|---|
| [JAVA] 다중 catch 블록 작성 시 주의점 : 예외 상속 계층의 이해 (0) | 2026.01.20 |
| [JAVA] 외부 라이브러리 없이 JSON/XML 파싱하기 : 표준 API의 숨겨진 힘 (0) | 2026.01.20 |
| [JAVA] PrintStream vs PrintWriter : 당신의 출력 코드가 전문적인지 확인하는 법 (0) | 2026.01.20 |
| [JAVA] Scanner vs BufferedReader : 성능과 효율을 결정짓는 입력 방식의 모든 것 (0) | 2026.01.20 |