본문 바로가기

Dev. Java

[예외처리] throw / throws , try-catch-finally 예외처리

출처 : http://pakt.tistory.com/


 ( Error )

: 화면에 잘못된 메시지를 출력하고, 실행을 멈추게 되는 프로그램 자체의 문제

: Error class 에서 파생

: 에러 관련 처리 코드가 정확치 않아도 컴파일 됨

ex) OutOfMemoryError ..

예외처리 ( Exception )

: 프로그램의 흐름이 끊어지지 않게 하기 위해서 필요한 부분.

: 오류가 생겼다고 해서 중간에 프로그램을 강제종료하지 않고, 정상적으로 마지막 부분까지 흘러가서 종료되게 하는 것.

: 문제가 발생될 것을 미리 예측하여 프로그램 과정중에서 잡아내는 것

: java.lang.package 의 Exception class 에서 파생 -> 모든 예외 클래스의 상위 클래스

ex) IOException ..




throws

: 현재 메소드에서 상위 메소드로 예외를 던지는 것

: 메소드 이름옆에 기재

: throws IOException //에러가 났을 경우에는 IOException 이라는 클래스가 처리한다는 뜻

: 메소드 선언시 메소드에서 예외를 처리하는 것이 아닌, 발생할 수 있는 예외를 명시하는 것

: try/catch 문으로 예외처리가 다 되지 않았을 경우, 현재의 메소드에서 처리할 수 없지만, 지금 이 메소드를 호출한 메소드가 알아서 처리하라고 던져주는(미뤄주는) 것

ex) public int Test(int num throws IOException{   ...  }

ex) public void method1(){
        try{
            ...
            method2();
        }catch(Exception e) {
            ...
        }
    }

method2() throws Exception{

...

}

->  만약 method2()에서 예외가 발생한다면, 

method2() 자체내에서는 예외처리가 불가하여,

method1()로 가서 처리하게 됨.


throw

: 메소드내에서 상위 블럭으로 예외를 던지는 것

: 어떠한 상황에서, 사용자(프로그래머)가 예외를 강제로 발생시킬 때 사용

try...catch 문 내에서 throw로 처리된 메시지는, catch 블럭내에서 처리된다.

억지로 에러를 발생시킬때도 사용되지만 현재 메소드의 에러를 처리한 후에, 상위 메소드에 에러 정보를 줌으로써 상위 메소드에서도 에러가 발생한 것을 감지할수 있습니다.

ex)

1. java.lang.Throwable 클래스 또는 이를 상속받은 클래스의 객체인 경우
    : throw   object;

try{
    .....
}catch(Exception e) {
      throw   e;
}


2. 객체 참조 변수 없이 새로운 Throwable 객체를 생성하여 예외를 발생시키는 경우
    : throw new ExceptionType(args);

class  Exception_test{
   public static void main(String[] args) {
       try {
           System.out.println("Before throw");
           throw new Exception("throw Exception");
       }
       catch (Exception e) {
           System.out.println("Exception : " + e);
       }
   }
}


사용자정의 예외처리

: 프로그래머가 필요한 경우, 예외 관련 클래스를 상속받아, 예외클래스를 정의하여 사용

: 형식

    class UserException extends Exception{
         public UserException(String message) { // 생성자 
             super(message); // 부모클래스인 Exception 클래스의 생성자를 호출하여 예외 객체 생성
         }
    }

: 예제1

class  UserException_test {
     public static void main(String[] args)     {
          try {
               String arg = args[0];
               if("blahblah".equals(arg)) {
                    throw new BlahException("블라 예외");
               } else {
                    System.exit(0);
               }
          } catch(BlahException e) {
               System.out.println(e + " 발생");
          }
     }
}
class BlahException extends Exception{
     public BlahException(String message) {
          super(message);
    }
}

-> 만약 blahblah 를 입력하면, 

" 블라 예외 발생 " 출력

: 예제2

class BlahException extends Exception{
    BlahException() {
     }
}
class UserException_test1{
     public static void main(String[] args)  {
          Blah blah = new Blah();
          try{
               String arg = args[0];
               System.out.println(blah.classBlah(arg));
          } catch(BlahException e){
               System.out.println("Exception " + e);
          } catch(Exception ex){
               System.out.println("Exception " + ex);
          }
     }
}
class Blah{
     public int classBlah(String bl) throws BlahException {
          if("classBlah".equals(bl)) {
               throw new BlahException();
          }
          return 0;
     }
}

-> 만약 인수를 classBlah 라고 주면 "Exception BlahException" 출력

-> 다른 인수를 넣으면 return값 0 을 출력

-> 인수를 넣지 않는 등의 다른 예외 발생시 " Exception + ex " 를 출력


try / catch / finally

try {

예외가 발생할 가능성이 있는 실행문(try블록)

}catch ( 처리할 예외 타입 선언 ) {

예외 처리문(catch 블록)

}catch ( 처리할 예외 타입 선언 ) {

예외 처리문(catch 블록)

}finally {  //finally 는 생략가능

예외 발생 여부와 상관없이 무조건 실행되는 문장(finally 블록)

}

-> catch 문은 여러개 사용 가능

출처 : http://ejs0414.blog.me/



throw / throws 가 필요한 이유

try { 

} catch (RedException re) { 

log.error("에러가 났습니다", re); 

throw new ParentException("어느어느부분에서 에러가 났습니다.", re); // re 를 인자로 같이 주는게 중요. 

-> "어느어느부분에서 에러가 났습니다." 는 생략가능
        --> throw new ParentException(re);   만으로도 가능

-> 예외가 발생하면 catch 에서 예외를 잡아 로그로 남기고

-> 예외를 상위 예외로 감싸서 상위로 throw 하면, 하위 예외 정보까지 함께 날아갑니다.
    : 결합도를 낮추기 위한 조치
    : 취하위 예외를 되도록 사용자가 정의한 상위 예외로 감싸는 것이 좋음
    : 나중에 유지보수에 용이함

-> 프로젝트를 할 때, 프로젝트를 합치고 난 뒤 에러가 발생하였을시에,
     각 클래스에서 알아서 예외처리를 해버리고, 호출한 상위 클래스에 아무것도 던져주지 않게 된다면,
     유지보수에 힘들기 때문에, 위와 같이 해줌

-> 프로그램을 코딩하게 될 경우, 여러개의 클래스로 나누어 작성,
     따라서, 예외가 여러곳에서 발생 할 수 있음
    -> 그러한 예외처리 코드를 여러곳에서 처리하는 것보다, 한곳으로 모아서 하기 위해서 필요함


throws ->

1. 메소드 뒤에 "throws 예외이름" 으로 기술하면, 그 메소드에서 예외가 발생했을 때 그 메소드를 호출한 메소드로 예외 처리는 넘긴다는 개념

2. 모든 메소드에서 예외 처리 코드를 기술하지 않아도 되기 때문에 한 개의 프로그램이 여러개의 클래스로 구성되는 경우 효율적인 기법


throw ->

1. throws 와 함께 사용됨

2. 프로그램이 각 라인을 실행해보고 예외가 있으면, 예외 처리를 하는 구조이지만, throw 를 사용하면 실행하기 전에 프로그래머가 직접 예외를 발생시킬 수 있음

3. 안전하게 예외를 처리하려는 의도에서 사용됨