
RuntimeException
Java에서는 프로그램 실행 중 나타나는 오류(exception or error)를 처리하기 위해 예외(Exception) 클래스를 제공한다.
그중 RuntimeException은 “런타임 예외(Runtime Exception)”로 불리며,
보통 예측 불가능한 프로그래밍 오류를 나타낼 때 사용된다.
RuntimeException을 직접 사용하거나, 그 하위 클래스를 사용하는 것
=> 이게 바로 흔히 말하는 “Unchecked Exception”이다.
반대로 RuntimeException을 상속하지 않는 예외들은 Checked Exception으로 분류된다.
Checked Exception vs Unchecked Exception 차이
| 검사 시점 | 컴파일 시점 — 예외 처리를 강제 | 런타임 시점 — 컴파일러가 검사하지 않음 |
| 선언 및 처리 필요 여부 | try-catch 또는 throws 키워드로 처리하거나 선언해야 한다 | 선언이나 처리 없이도 됨 개발자 선택에 따라 catch 가능 |
| 주로 발생하는 상황 | 파일 I/O, 네트워크, DB 접근 등 외부 리소스와의 상호작용 중 발생 가능한 예외 |
프로그래밍 실수나 논리 버그 (예: null 참조, 배열 인덱스 벗어남, 잘못된 연산) |
| 예시 | IOException, SQLException, ClassNotFoundException 등 |
NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException, ArithmeticException 등 |
- Checked Exception은 예측 가능한 실패 상황(예: 파일이 없어서 읽을 수 없음)에 대비하도록 설계
→ 호출자는 반드시 “예외가 발생할 수 있음”을 인지하고 처리하거나 상위로 던져야 한다. - Unchecked Exception은 프로그래밍 오류나 개발자 실수를 나타내며,
→ 컴파일 시점에서는 알 수 없고, 런타임 시점에만 드러나므로, 개발자에게 필요할 때만 책임지고 처리할 수 있게 한다.
“회복 가능한 예외인가?” vs “코드 논리·버그인가?”라는 관점에서 선택이 달라진다.
RuntimeException (Unchecked Exception) 의 특징과 주의점
✔️ 특징
- 메서드 시그니처에 throws 선언이 필요 없다.
- 호출 측에서는 예외를 강제적으로 처리할 필요가 없다.
- 예외 처리에 얽매이지 않아 코드가 간결해질 수 있다.
- 주로 논리적 오류나 프로그래머 실수에 의해 발생하는 예외가 많다
- String s = null; s.length(); // NullPointerException 등
✔️ 주의할 점
Unchecked 예외는 “무시”하기 쉽다. 예외 처리를 생략할 수 있기 때문이다.
따라서 다음과 같은 문제가 생길 수 있다:
- 예외 발생 시 전체 애플리케이션이 예상치 못하게 종료될 수 있다.
- 예외 상황을 엉뚱하게 무시하거나 숨기면서, 버그가 조용히 누적될 수 있다.
- 예외가 발생할 수 있는 지점을 명확히 예측하기 어렵다 — 특히 외부 자원 접근이 섞인 코드에서는 더욱 그렇다.
Unchecked Exception을 남발하면, “누가 어디서 왜 에러가 났는지” 추적이 어려워진다.
언제 Checked Exception, 언제 RuntimeException (Unchecked) 을 써야 할까?
- 회복 가능한 실패가 예상되는 상황 → Checked Exception
예: 파일이 없어서 읽지 못했다면, 이걸 호출자에게 알려주고 “대체 행동”을 하게 할 수 있음 - 프로그래머 실수 / 논리 오류 / 예측 불가 내부 버그 → Unchecked Exception (RuntimeException)
예: null 참조, 잘못된 인자 전달, 배열 인덱스 벗어남 등 — 이런 건 코드 수정으로 해결해야 함 - API 설계 시
- 만약 호출자가 “예외에 대비해야 한다”고 강제하고 싶다면 → Checked Exception
- 예외가 발생하면 호출자가 속성적으로 복구할 수 없고, 단순히 호출이 잘못된 것이라면 → Unchecked Exception
예시 코드
// Checked Exception 예시
public void readFile(String path) throws IOException {
FileInputStream in = new FileInputStream(path);
// ...
}
// 호출 쪽: 반드시 try-catch 또는 throws 선언
try {
readFile("somefile.txt");
} catch (IOException e) {
// 파일을 읽을 수 없을 때 대체 동작
// e.g. 사용자에게 알림, 기본값 사용 등
}
// Unchecked Exception 예시
public int divide(int a, int b) {
return a / b; // b가 0이면 ArithmeticException (Unchecked)
}
public void process(String input) {
if (input == null) {
throw new IllegalArgumentException("input must not be null");
}
// ...
}
Unchecked 예외는 선언이나 처리 없이도 던질 수 있다.
하지만 이런 경우엔 반드시 예외 발생 가능성을 코드 주석이나 문서로 남겨야 한다
RuntimeException을 포함한 예외 설계의 팁
- RuntimeException 계열(언체크드 예외)은 프로그래밍 오류나 불가능한 상황을 나타낼 때 사용
- 예측 가능한 실패 (외부 리소스, 사용자 입력 오류 등)은 Checked Exception으로
- API 설계 시 호출자에게 “예외 처리 책임을 누가 지는가?”를 명확히 고려
- 무작정 모든 예외를 RuntimeException으로 바꾸면 코드가 간결해질 수 있지만, 예외의 의미와 책임 구조가 흐트러질 수 있다.
Java에서 RuntimeException은 “불완전한 코드 / 예측 불가능한 상황”을 나타내는 강력한 도구이다.
하지만 그만큼 책임감 있게 사용해야 한다.
어떤 예외를 던질지, 어떤 예외를 반드시 처리해야 할지.
그 설계가 코드의 안정성과 유지보수성을 좌른다.
반응형
'IT > JAVA' 카테고리의 다른 글
| getOrDefault() vs computeIfAbsent() (0) | 2025.12.06 |
|---|---|
| ReentrantLock 락 제어 (0) | 2025.12.06 |
| 동기화 vs 원자적 연산 (1) | 2025.07.24 |
| ConcurrentHashMap – 멀티스레드 환경에서 안전하게 Map 사용하기 (1) | 2025.07.24 |
| Java String 클래스 (0) | 2025.04.15 |