평소 체크 예외와 언체크 예외의 용도를 생각하지 않고 사용했던 것 같아 정리를 해본다.
체크 예외(Checked Exception)와 언체크 예외(Unchecked Exception)
1. 체크 예외 ( Checked Exception )
- 컴파일러가 예외를 확인하므로 컴파일 타임에 예외를 발생시킨다.
- 예외를 처리하기위해 try-catch 블록이나 throws 를 사용해야 한다.
ex> IOException, FileNotFoundException
public class CheckedExceptionExample {
public static void main(String[] args) {
try {
File file = new File("nonexistent.txt");
FileInputStream fileInputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
System.out.println("파일을 찾을 수 없습니다.");
// e.printStackTrace();
}
}
}
2. 언체크 예외 ( Unchecked Exception )
- 컴파일러가 예외를 확인하지 않으며 주로 개발자의 실수로 발생한다.
- throws 를 생략하고 실행할 수 있다.
ex> RuntimeException, ArrayIndexOutOfBoundsException
/* 런타임 하위 클래스의 예외가 발생함을 확인할 수 있다 ( 컴파일 X ) */
public class UncheckedExceptionExample {
public static void main(String[] args) {
int[] arr = new int[5];
int value = arr[10]; // 배열의 범위를 벗어나는 인덱스에 접근 시도
}
}
예외를 나누는 기준
그렇다면 체크 예외와 언체크 예외는 각각 언제 사용하는 것이 좋을까 ?
오라클 문서에서는 클라이언트가 예외로부터 회복할 수 있는 경우에는 체크 예외를 클라이언트가 예외로부터 아무것도 할 수 없는 경우 언체크 예외를 사용하라는 지침이 있다.
예를 들어 위의 체크 예외에서처럼 파일이 없는 경우 사용자는 경로를 확인하거나 다른 파일을 선택할 수 있다.
그렇지만 배열의 범위를 벗어나는 코드로 작성되어있는 경우 코드를 수정하지 않는 한 문제를 회복할 수 있는 방법이 없다.
이펙티브 자바에서도 " 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 " 라는 내용을 볼 수 있다. 구현하는 예외는 모두 RuntimeException의 하위클래스여야하고 Exception, RuntimeException, Error 를 상속하지 않는 throwable 을 만들 수 있는데 throwable 클래스들은 대부분 오류 메시지 포캣을 상세히 기술하지 않기 때문에 사용하지 않는 것을 권장한다.
또한, 체크 예외인지 아닌지 확실하지않다면 언체크 예외를 권장하고 체크 예외라면 복구에 필요한 정보를 알리는 메서드를 제공하는 것을 권장한다.
그러면 이 지침대로 Spring 웹에도 똑같이 적용하면 되는가 ?
체크 예외 코드에 인터페이스 도입시 문제점이 있다. 이는 강의를 통해 확인할 수 있었다.
체크 예외는 컴파일러가 예외를 체크해주기 때문에 항상 명시적으로 예외를 잡아서 처리하거나 throws 로 선언을 해야 한다. 이는 두 가지 문제점을 제시한다.
1. 복구 불가능한 예외 : SQLException (체크 예외) 의 경우 복구가 불가능하다.
2. 의존 관계에 대한 문제 : 컨트롤러나 서비스에서 연쇄적으로 throws 예외를 선언해야한다.
그렇기 때문에 체크 예외는 비즈니스 로직상 의도적으로 던지는 예외에만 사용하고 기본적으로 언체크 예외를 사용하는 것을 권장한다.
참고
https://docs.oracle.com/javase/specs/jls/se8/html/jls-11.html
https://docs.oracle.com/javase/tutorial/essential/exceptions/
https://www.geeksforgeeks.org/exceptions-in-java/
Bloch, J. (2018). Effective Java (3rd ed.).
김영한, 스프링 DB 1편 - 데이터 접근 핵심 원리, https://inf.run/AomUA
'JAVA' 카테고리의 다른 글
[Java] ArrayList 와 HashMap (0) | 2024.04.07 |
---|---|
[Java] LocalDateTime 과 Instant (0) | 2023.12.31 |
[이펙티브자바] Item1. 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2023.10.15 |
[Java] Access Level 에 관하여 (0) | 2023.09.24 |
[Java] stream.map() 동작 및 예제 (0) | 2023.08.20 |