[자바/JAVA] 예외(Exception) 처리에 대해, try ~ catch | throw

2가지 예외(Exception)

프로그램에 에러가 발생하면 자바는 동작을 멈추고 에러 메시지를 보낸다. 이를 자바가 예외를 발생시켰다고 말한다. 예외가 발생하면 예외를 발생시킨 코드가 실행되지 않을 뿐만 아니라 프로그램 자체가 동작할 수 없게 된다. 때문에 개발자는 이런 상황을 대비 해야 한다. 자바에서는 java.lang.Exception 클래스를 통해 예외를 관리한다. 자바의 모든 클래스는 java.lang.Exception을 상속받는다.

 

예외는 크게 두 가지로 분류된다.

  • 일반 예외(Exception)
  • 실행 예외(Runtime Exception)

이클립스 같은 IDE를 통해 코딩을 하다보면 빨간 줄로 코드가 컴파일될 수 없다는 경고가 종종 표시된다. 이처럼 자바 컴파일러가 소스 파일을 컴파일할 때 확인할 수 있는 예외를 일반 예외라고 한다.

 

반면 컴파일은 문제없이 되지만 막상 실행했을 때 예외를 알리는 경우가 있는데 이를 실행 예외(Runtime Exception)라 한다. 글에서 서술할 try ~ catch 예외 처리는 Runtime Exception을 대비하기 위함이다.

try ~ catch

try {
    // 예외 발생 가능한 코드
} catch(예외클래스 e) {
    // 예외 처리
}

try 블록{}에는 예외가 발생할 수 있는 코드를 넣는다. catch ()에는 예외 클래스 이름과 객체명을, 블록{}에는 해당 예외가 발생할 경우 실행할 코드를 작성한다.

 

아래는 예외가 발생하는 예제다.

public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}

출력값

선언한 myNumbers의 배열 크기가 3인데 10번째 인덱스 출력을 요청했기 때문에 ArrayIndexOutOfBoundsException에러가 발생했다.

 

try ~catch 문을 이용해 ArrayIndexOutOfBoundsException이 발생할 경우에도 정상적으로 프로그램이 실행되도록 해보자. 코드에 에러가 있음에도 프로그램을 무사히 실행시키는 것이다.

public class Main {
      public static void main(String[] args) {
        int[] myNumbers = {1, 2, 3};

        try {
        System.out.println(myNumbers[10]);
        } catch (ArrayIndexOutOfBoundsException e){
            System.out.println("배열 크기를 확인하세요");
        }
      }
    }

출력값

예외의 종류는 ArrayIndexOutOfBoundsException 외에도 여럿 있다. 어떤 예외가 발생할지 예상하고 그에 맞는 예외 처리를 하는 건 개발자의 판단이다.

발생 가능한 예외들

catch(Exception)

만약 어떤 예외가 발생할지 판단이 서지 않는다면 어떻게 해야 할까? catch (Exception e)을 사용하는 방법이 있다. 위에서 언급했듯 자바의 모든 클래스는 java.lang.Exception를 상속한다. 그런데 세분화된 예외 클래스들은 java.lang.Exception의 하위 클래스다. 즉 Exception으로 예외를 처리하면 품고 있는 모든 서브 클래스들의 기능을 수행할 수 있다. 자세한 내용은 JDK API 문서에 있다.

 

그렇다면 굳이 구체적인 예외 클래스를 명시할 필요가 있나 싶은 생각도 든다. 이와 관련해서는 '구체적인 예외를 명시하는 게 좀더 좋은 코드'로 인정 받으며 이를 권장하는 듯 하다. 단순히 Exception을 사용한다는 건 해결 가능한 에러와 다른 변수에 의한 예상하지 못한 프로그래밍 오류를 구분하지 않는다는 의미이고 이는 궁극적으로 서비스의 사용자 경험에 악영향을 줄 수 있기 때문이다. 참고 : Specific Exceptions vs Exception

finally

try {
    // 예외 발생 가능한 코드
} catch(예외클래스 e) {
    // 예외 처리
} finally {
    // 반드시 수행됨
}

try ~ catch 문이 종료되고 결과에 상관없이 수행되는 게 finally 구문이다. 예외가 발생하지 않아도 수행되고 예외가 발생해도 수행된다.

public class Main {
      public static void main(String[] args) {
        int[] myNumbers = {1, 2, 3};

        try {
        System.out.println(myNumbers[10]);
        } catch (Exception  e){
            System.out.println("배열 크기를 확인하세요");
        } finally {
            System.out.println("반드시 출력");
        }
      }
    }

출력값

throw exception

경우에 따라 try ~ catch를 사용하지 않고 메서드를 호출한 곳으로 예외를 떠넘길 수 있다. 이때 throw를 사용한다.

 

아래 예제는 if문에 throw exception 처리를 하고 특정한 경고 문구를 띄운다.

public class Main {
      static void checkAge(int age) {
        if (age < 18) {
          throw new ArithmeticException("18세 미만이어야 합니다");
        }
        else {
          System.out.println("승인 됐습니다");
        }
      }

      public static void main(String[] args) {
        checkAge(15); // age 값 15로 checkAge 메서드 호출
      }
    }

출력값

 


예제 출처: w3c

반응형

댓글

Designed by JB FACTORY