본문 바로가기
프로그래밍/Java

[java] exception 처리하기 - throws에 관하여

by 사바라다 2020. 4. 22.

안녕하세요. 오늘은 이전 시간에 이어 exception에 대해서 좀 더 알아 보는 시간을 가지고자 합니다. 우리가 이전 포스터에서 확인한 바에 따르면 exception은 JVM에서 일어나고 call stack을 따라서 처리된다고 배웠습니다. 즉, Unchecked exception의 경우 메서드 체인에 의해서 호출한 곳에 exception에 해당하는 catch가 있으면해당 해당 catch method가 실행되는 것입니다. 그렇다면 throws는 왜 있는걸까요?

결론부터 말씀드리면 unchecked exception의 경우에는 즉, RuntimeException을 상속 받는 Exception의 경우 throws는 아무런 의미도 가지지 않습니다. throws는 checked exception의 처리 방법중 하나인것입니다.

오늘은 throws를 checked exception과 unchecked exception에 사용해보며 비교해보는 시간을 가지도록 하겠습니다.

checked exception을 throws

throws를 checked exception에서 사용해보도록 하겠습니다.

@Test
public void exceptionSample() {
    try {
        exceptionOccurredMethod();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

private void exceptionOccurredMethod() throws FileNotFoundException {
    FileInputStream fi = new FileInputStream(new File("hello"));
}

위 예제를 보면 exceptionSample이라는 method에서 exceptionOccurredMethod를 호출합니다.exceptionOccurredMethod 메서드에서는 FileInputStream 클래스를 생성하고 있는데 이 클래스는 생성자에 FileNotFoundException가 throws로 붙어 있습니다. 이 예외는 checked exception입니다. 따라서 예외처리가 필요하며 그것을 exceptionOccurredMethod에서 throws로 호출자에게 던졌습니다. 호출을 한 exceptionSample 메서드에서는 FileNotFoundException 예외를 처리하던지 회피하지 않으면 에러가 발생하게 됩니다. 이렇게 checked exception에서는 예외처리가 강제되기 때문에 try-catch 또는 throws를 통해 처리해 주는것이 타당하다는 것을 알 수 있었습니다.

unchecked exception을 throws

throws를 unchecked exception에서 사용해보도록 하겠습니다. 먼저 throws를 사용하지 않았을 경우입니다.

@Test
public void exceptionSample() {
    try {
        exceptionOccurredMethod(null);
    } catch (NullPointerException e) {
        System.out.println("exceptionSample");
    }
}

private void exceptionOccurredMethod(String hello) {
    File file = new File(hello);
}

위 로직은 File 인스턴스를 만들때 null을 인자로 사용하고 있습니다. 이렇게 하면 File의 내부에서의 사전검증로직으로 인해 NullPointerException이 발생합니다. NullPointerException은 unchecked exception으로 별도의 처리로직이 없더라도 컴파일에는 지장이 없습니다. 그리고 호출한 메서드인 exceptionSample 쪽에서는 throws를 exceptionOccurredMethod에서 주지 않았더라도 해당 try-catch 로직은 정상적으로 동작하여 Console에는 exceptionSample이라고 출력됩니다. 이 이유는 이전 포스팅에도 언급한것 처럼 exception의 cal stack때문입니다.

call stack의 과정

이제 throws를 사용해 보겠습니다.

@Test
public void exceptionSample() {
        exceptionOccurredMethod(null);
}

private void exceptionOccurredMethod(String hello) throws NullPointerException{
    File file = new File(hello);
}

위와 같이 코드를 작성했습니다. 컴파일에러도 발생하지 않고 exception은 JVM기본 exception이 발생합니다. uncheced exception은 예외를 강제하기 때문에 throws로 던진다고 해도 호출한 메서드에서 예외를 강제로 처리해야하거나 하지 않기때문입니다.

마무리

오늘은 throws를 unchecked exception과 checked exception으로 나누어서 테스트 해보고 그결과를 확인해보았습니다. 앞서 말했듯이 unchecked exception의 경우에는 즉, RuntimeException을 상속 받는 Exception의 경우 throws는 아무런 의미도 가지지 않습니다. 라는 것을 증명 할 수 있었습니다. 굳이 unchecked exception에 throws를 쓴다는 것은 호출한 메서드가 try-catch로 예외처리를 해주는 것을 권장한다는 느낌을 줄 수 있을것 같습니다.

오늘은 여기까지 입니다.

도움이 되셨다면 하트부탁드려요.

감사합니다.

참조

https://www.geeksforgeeks.org/throw-throws-java/

댓글