Java 예외 처리 - try ~ catch 언체크 예외
언체크 예외가 있다. 다른 이름으로 런타임 예외라 한다.
RuntimeException 예외 특징
- 그 하위 예외는 언체크 예외로 분류
- 컴파일러가 예외를 체크하지 않는다.
- 체크 예외와 기본 동작은 같으나, throws 선언이 필요가 없어서 생략이 가능하다. 생략되더라도 자동으로 예외를 던지도록 되어있다.
쳬크 예외와 언체크 예외
- 체크 예외는 예외 상황을 잡아서 처리하지 않은 경우, 항상 throws 키워드를 사용해야 한다.
- 언체크 예외는 예외 상황을 잡아서 처리하지 않은 경우, throws 키워드 생략이 가능하다.
언체크 기본적인 예제 코드
UncheckedException.class
// RuntimeException 상속 받은 경우 예외는 언체크 예외가 되버린다.
public class UncheckedException extends RuntimeException{
public UncheckedException(String message) {
super(message);
}
}
Client.class
public class Client {
public void call() {
// 문제 발생시키기
throw new UncheckedException("boom");
}
}
- CheckedException 예외를 발생시킬 때와 다르게 throws 키워드가 없어도 컴파일 오류가 발생되지 않는다.
Service.class
public class Service {
Client client = new Client();
public void callCatch() {
try {
client.call();
} catch (UncheckedException e) {
// 예외 처리 로직
System.out.println("예외 처리하기, message = " + e.getMessage());
}
System.out.println("정상적인 흐름");
}
public void callThrow() {
client.call();
}
}
- client.call() 예외 발생시 throws 키워드가 없어도 자신을 호출한쪽으로 자동으로 예외를 던진다.
Main.class
public class Main {
public static void main(String[] args) throws CheckedException {
Service service = new Service();
service.callCatch();
System.out.println("프로그램 종료");
}
}
예외 처리하기, message = boom
정상적인 흐름
프로그램 종료
정상적으로 동작하는 모습을 볼 수 있다.
모든 클래스가 예외를 던진 상황
Main 호출부에서 예외를 반환하는 코드로 변경해보도록 한다.
Main.java
public class Main {
public static void main(String[] args) throws CheckedException {
Service service = new Service();
service.callThrow();
System.out.println("프로그램 종료");
}
}
Exception in thread "main" UncheckedException: boom
at Client.call(Client.java:4)
at Service.callThrow(Service.java:16)
at Main.main(Main.java:7)
Client, Service, Main 모든 클래스가 Client 발생시킨 예외를 처리하지 못하고 예외를 던져 프로그램이 종료되었다.
종료 전 콘솔로 예외 정보와 스택 트레이스를 모두 출력해주는 것을 살펴볼 수 있다.
언체크 예외 요약
언체크 예외는 throws 예외 키워드를 생략할 수 있다.
장점
- 테스트용 신규 메소드를 작성이 필요할 때 하나하나 throws 지정하지 않아도 된다.
단점
- 언체크 예외는 개발자 실수로 예외가 필요한 상황에 누락할 수 있다. 체크예외로 컴파일러로 통해 누락한 예외를 잡아준다.