예외처리 : throws 선언

 - 예외를 발생시키는 코드를 사용할 때 당장 예외 처리를 하고 싶지 않다면,

   메서드 선언부에 그 예외 정보를 적시하면 된다.

   그러면 그 메서드를 호출하는 쪽에서 처리할 것이다.

 - 즉 해당 메서드에서 어떤 예외가 발생하는지 알리는 것이 목적이다.




throws 예외처리 예제 I


public class Test08 {
  public static void main(String[] args)
      throws Exception, IllegalArgumentException, NumberFormatException {
     
      if (args.length < 1)
        throw new IllegalArgumentException("애플리케이션 아규먼트가 없습니다.");
      int age = Integer.parseInt(args[0]);
     
      if (age < 1)
        throw new Exception("나이가 유효하지 않습니다.");
     
      System.out.println(age);
  }

 }



* 참고

   - throws 는 메서드 선언부에 '단수 or 복수 개'의 예외를 던지며

     main()에 써서 예외가 발생했을 경우, 바로 선언부로 돌아가 예외처리를 하고

     프로그램은 종료된다.

   - throw는 예외가 발생했을 때, 하나의 예외 인스턴스를 던질 때 사용한다. 





** 참고 - 다음 예제

    - java.lang.RuntimeException 계열의 예외가 발생할 때는 

      예외를 처리하는 것이 선택사항이다.

      컴파일러가 강제로 요구하지 않는다. 

      => 예외를 처리하는 try ~ catch ~ 을 사용하지 않아도 되고,

           메서드 선언 부에 throws를 적시하지 않아도 된다.

    - 이유 :

       스텔스 모드로 예외를 전달하기 위해 특별히 정한 규칙이다.




throws 예외처리 예제 II - 스텔스 모드


public class Test12 {
 
  static void m1(int v) {
    m2(v);
  }
  static void m2(int v) {
    m3(v);
  }
  static void m3(int v) {
    m4(v); // 자기가 직접 발생시키는 에러가 아니라 m4()가 발생시키는 에러라 할지라도
           // m3()에서 에러를 처리해줘야 한다.
  }
 
  // 예외를 발생시키는 메서드(m4())와 그 메서드를 호출.
  static void m4(int v) {
      if (v < 0)
        throw new RuntimeException("음수는 허용하지 않습니다.");
      System.out.println(v);
  }
 
  public static void main(String[] args) {
    try {
      if (args.length < 1) {
        System.out.println("[사용법] java -cp bin step17.Test11 숫자");
        return;
      }
        m1(Integer.parseInt(args[0]));
    } catch (NumberFormatException e) {
      System.out.println("프로그램 아규먼트는 숫자여야 합니다.");
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println("안녕! 디지몬");
  }
}



*** 참고

예외를 발생시키는 메서드를 사용한다면 반드시 둘 중 하나는 해야 한다.

 1) try ~ catch ~ 로 예외를 정확히 처리하거나,

 2) 이 메서드 안에서 예외가 발생한다고 메서드 '선언부'에 적시하거나.



스텔스 모드를 사용하는 이유는 예외가 발생하더라도, 상위 메서드까지 조용히 

던지기 위함이다. 그렇다고 하더라도 예외는 최소한 main()에서는 개발자가 처리해야

한다. 만약 main()에서까지 예외가 처리되지 않는다면 예외 발생시 JVM에까지 전달될

것이고 그 결과 프로그램이 종료될 것이다.




블로그 이미지

필로그래머

,

[Java] 자바 (2) 예외처리 - 1. throw throwable 2. Error 예외와 Exception 예외 비교


예외처리 : 예외 발생 시 그 정보를 전달하고 전달 받는 방법

 - 예외 정보를 호출자에게 전달하는 방법

    throw [Throwable 객체];

     - 예외 정보를 담은 객체란 무엇인가?

        java.lang.Throwable 타입의 객체이다.

        - java.lang.Throwable 클래스 계층 구조

    Throwable           

     | --> Error

     | --> Exception

             | --> RuntimeException

                     | --> NullPointerException

             | --> IOException

               | --> FileNotFoundException

               | --> EOFException

       | -->  SQLException 

                   | -->  그외 (..)


        - 예외 종류

           1) 시스템 예외(Error 타입 예외)

               - JVM이 발생시키는 예외이다.

    - 개발자가 처리하는 예외가 아니다.

    - 개발자가 처리하기엔 치명적인 예외라서 가능한 JVM을 종료해야 한다.

    - 이 예외가 발생했을 때,

       개발자는 JVM이 종료되기 전에 작업 중인 파일을 저장하거나

       예외에 대한 로그를 파일에 쓰거나

       사용자에게 예외 상황을 출력하는 등의 마무리 작업을 하고 

       JVM을 종료한다.


           2) 애플리케이션 예외(Exception 타입 예외)

               - 애플리케이션에서 발생하는 예외이다.

               - 개발자가 처리해야 하는 예외이다.

               - 예외를 처리한 후에 애플리케이션을 계속 실행할 수 있다.


 - 예외 정보를 받는 방법

    try {

예외를 던지는 코드

    } catch (예외를 받을 변수 선언) {

예외를 처리하는 코드

    }




예외처리 예제


public class Test03 {
  // 메서드를 실행하다가 예외를 던질 수 있는 경우
  // => 메서드 선언부에 어떤 예외가 던져질 수 있는지 적어야 한다.
  public static float divide(float a, float b) throws Throwable{
    if (b == 0) {
      // 예외 상황이 발생하면, 호출자에게 그 정보를 전달해야 한다.
      throw new Throwable("0으로 나누지 마세요!");
    }
    return a / b;
  }
 
  public static void main(String[] args) {
    try { // 예외를 던질 수 있는 코드는 try 블록 안에 둔다.
      float result = divide(10, 2);
      System.out.println(result);
      result = divide(10, 0);
      System.out.println(result);
    } catch (Throwable ex) {
      System.out.println(ex.getMessage());
    }
System.out.println("Hello"); // 예외가 발생하든 안하든 실행!
  }

}


 - 실행결과 : 

5.0

0으로 나누지 마세요!



 - 예외 처리 문법의 이점 

    1) 메서드가 리턴하든 안하든, 

       리턴하는 값의 타입이 무엇이든 

       호출자에게 예외 정보를 전달할 수 있다.

    2) 예외를 처리하는 입장에서는 try 블록 안에는 예외 상황이 아닐 때의 

        작업 코드를 두고, catch 블록 안에는 예외를 처리하는 코드를 둠으로써

        정상 작업 코드와 예외 처리 코드를 분리하는 효과가 있다.

         -> 코드의 가독성 ↗

    3) 예외가 발생하더라도 적당한 처리를 한 후

        시스템을 멈추지 않고 계속 실행시킬 수 있다.



블로그 이미지

필로그래머

,