자바에서 예외처리를 하면 throw
와 throws
예약어를 자주 접하게 된다. throw
는 아래처럼 사용하는 것을 많이 봤을 것이다. "throw
뒤에 오는 Exception
객체로 예외를 발생시키는구나"하고 그 역할을 추론할 수 있다. 하지만 메소드 시그니쳐에 사용되는 throws
어떤 곳에서는 사용되고 또 어떤 곳에서는 사용되지 않는다. 언제 사용하는 것일까?
public void validate(String name) {
if (name.isBlank())
throw new IllegalArgumentException();
}
public void queryDatabase() throws IOException {
...
}
throws
는 메소드 시그니쳐의 일부로, 메소드를 호출하는 클라이언트에게 메소드의 동작 중 어떤 예외가 발생할 수도 있으므로 예외 처리해줘야한다는 것을 알려준다
접근_제어자 반환_타입 메소드명(인자) throws 예외1, 예외2, ...
형태로 여러 예외를 추가할 수도 있다
확인된 예외가 발생할 수 있을 경우 반드시 throws
로 추가해줘야하고 미확인 예외의 경우 추가할 수는 있으나 추가하지 않는게 권장된다.
자바의 예외는 크게 확인된 예외와 미확인 예외로 나눌 수 있다
확인된 예외 :
프로그램의 제어 밖에 있는 예외들. 컴파일 시점에 예외처리 여부를 확인한다
모든 RuntimeException
을 상속하지 않는 예외
ex) FileNotFoundException, SQLException
미확인 예외 :
프로그램 로직의 오류로인한 예외들. 런타임 시점에 예외처리 여부를 확인한다
모든 RuntimeException
을 상속하는 예외
ex) ArrayIndexOutOfBoundsException, IllegalArgumentException
만약 클라이언트가 예외로부터 회복하는 것을 어느정도 기대할 수 있다면, 확인된 예외로 한다. 만약 클라이언트가 예외로부터 회복할 수 없다면, 미확인 예외로 한다.
오라클의 자바 문서는 어떤 예외를 사용할지에 대해 위와 같이 기술한다. 회복을 기대한다는 것이 애매하게 느껴진다. 이 부분에 대해서는 나중에 더 자세히 찾아봐야겠다.
public class CheckedExceptionTest {
public static void main(String[] args) {
throwsCheckedTest(); // 확인된 예외를 발생하나 코드에서 예외처리를 하지 않아 컴파일에 실패한다
}
static void throwsCheckedTest() throws Exception {
throw new Exception("확인된 예외 throws 테스트");
}
}
// 실행 결과
>> java: unreported exception java.lang.Exception; must be caught or declared to be thrown
public class UncheckedExceptionTest {
public static void main(String[] args) {
throwsUncheckedTest(); // 예외처리를 하지 않아도 컴파일된다. 실행시 RuntimeException 발생
}
static void throwsUncheckedTest() throws RuntimeException {
throw new RuntimeException("미확인 예외 throws 테스트");
}
}
// 실행 결과
>> Exception in thread "main" java.lang.RuntimeException: 미확인 예외 throws 테스트
at Main.throwsUncheckedTest(Main.java:9)
at Main.main(Main.java:3)
위의 코드와 결과에서 볼 수 있듯이 미확인 예외는 throws에 추가 가능하지만 예외처리가 강요되지 않기 때문에 메소드 시그니처를 통해 정보를 전달하는 것 이외에 역할은 하지 못한다. 반면 확인된 예외는 throws를 통해 콜 스택의 다른 메소드에게 예외처리를 넘길 수 있다. throws
를 시그니쳐에 작성하지 않고, 확인된 예외를 메소드 내에서 처리하지도 않을 경우 컴파일 에러가 발생한다.