시작하기에 앞서...
- 자바에서 예외(Exception)는 크게 두 가지로 나뉜다: CheckedException과 UncheckedException
- 그리고 UncheckedException의 종류들 중에 자주 나오는 오류가
RuntimeException
- 강의 실습 중 ‘비밀번호 검증 실패 시 RuntimeException 발생’ 로직을 구현하며 왜 필수 처리 예외가 아닌지, 또 이들 사이의 차이는 뭔지 궁금해서 직접 정리해봤다.
✅ 예외의 분류
예외 타입 | 상속 구조 | 처리 강제 여부 | 주요 예시 |
---|
CheckedException | Exception (단, RuntimeException 제외) | ✅ try-catch 또는 throws 필수 | IOException , SQLException , ParseException 등 |
UncheckedException | RuntimeException 및 그 하위 클래스 | ❌ 처리 선택사항 | NullPointerException , IllegalArgumentException 등 |
Error (참고용) | Error | ❌ 처리 불가 (시스템 오류) | OutOfMemoryError , StackOverflowError 등 |
이렇게 블로그랑 공식 사이트 등을 돌아보며 하나의 표로 정리한 결과 위와 같이 나온다. 그렇다면 의문이 생긴다. 그렇다면 왜 UncheckedException은 처리를 강제로 하지 않는 것일까? 그래서 좀 더 자세히 찾아보니 여러 글을 취합해보니 아래와 같은 결과가 나왔다.
RuntimeException
이 필수 처리가 아닌 이유
1. 컴파일러는 외부 요인에 대한 예외만 강제처리한다.
- 예를 들어 파일이 없거나, 네트워크가 끊기는 경우는 개발자가 예상은 할 수 있지만 직접 해결은 못하는 경우가 발생한다.
- 이런 예외는 반드시
try-catch
나 throws
를 통해 컴파일 시점에 예외 처리가 강제된다.
FileReader reader = new FileReader("void-file.txt");
2. RuntimeException
은 개발자의 실수
- 대부분 개발자가 방심해서 생기는 오류 → null 체크 안 함, 인덱스 범위 벗어남 등의 오류들
String str = null;
System.out.println(str.length());
- 개발자가 충분히 사전에 테스트 코드나 디버깅을 통해 체크하면 방지 가능하므로 컴파일러가 굳이 체크하지 않는다.
3. 불필요한 try-catch 남발을 막기 위함
- 만약
NullPointerException
같은 것도 강제로 처리하게 한다면 코드는 지저분해지므로 협업에 문제만 생긴다!
실습 예시로 구분해보면...
1. CheckedException – 파일 읽기
public void readFile() throws IOException {
FileReader reader = new FileReader("test.txt");
}
IOException
은 CheckedException → 반드시 예외 처리 필수
2. UncheckedException – NPE
public void printLength(String input) {
System.out.println("length = " + input.length());
}
input
이 null
이면 NullPointerException
발생 → 처리 강제 X
3. 강의 실습 – 비밀번호 검증 실패
public void validatePassword(String inputPassword, String storedPassword) {
if (!inputPassword.equals(storedPassword)) {
throw new PasswordMismatchException("비밀번호가 일치하지 않습니다.");
}
}
PasswordMismatchException
은 RuntimeException
상속
- 비즈니스 검증 로직 실패 → 개발자 책임이므로 예외 처리를 개발자가 바로 처리할 수 있다.
결론을 내리자면...
상황 | 예외 유형 | 이유 |
---|
사용자 입력 값 검증 실패 | RuntimeException | 개발자 로직으로 충분히 방지 가능 |
외부 시스템 연결 실패 (파일, DB 등) | CheckedException | 외부 상황이 원인, 실패 가능성 항상 존재 |
코드 실수로 인한 문제 (NPE 등) | RuntimeException | 컴파일러가 강제하지 않음, 개발자가 직접 고쳐야 함 |
비즈니스 로직 위반 (ex. 비번 틀림) | 커스텀 RuntimeException | 의미 있는 메시지와 함께 명시적 처리 가능 |
결론
RuntimeException
은 개발자의 코드 실수나 검증 실패를 나타내기 위한 예외이므로 자바에서 의도적으로 오류 발생을 시키지 않는다.
- 컴파일러는 외부 환경에 의한 오류만 강제할 뿐이므로 런타임 오류같은 경우에는 개발자 스스로가 확인하고 처리해야한다.
그럼 언제 써야 할까?
- 강의 실습처럼 비밀번호 일치 여부 같은 비즈니스 로직은 RuntimeException으로 처리하는 것이 적절하다고 판단된다.
또다른 의문
- Throwable, Exception 등이 클래스로 저장된 이유가 무엇이길래 클래스로 정해진걸까? 굳이 해야할 이유가 있을까? 관련 자료에 짤막하게 나온게 있긴한데 snapshot을 저장할 정도면 그냥 저장해도 될 정도인데 클래스인 이유를 좀 더 찾아봐야겠다.
이 의문은 나중에 더 자료들을 찾으면서 분석해 봐야겠다.
참고자료