[JAVA] 예외 처리 Exception try-catch-finally, throws, 사용자 정의 예외

2019. 10. 1. 11:44 JAVA/Java

예외 처리 Exception try-catch-finally, throws, 사용자 정의 예외


자바는 프로그램 실행중에 발생할 수 있는 예외 처리문을 제공한다.

자바의 예외 처리는 예외가 발생한 메서드 내에서 직접 처리하는 방법과 예외가 발생한 메소드를 호출한 곳으로 예외 객체를 넘겨주는 방법, 그리고 사용자 정의 예외를 생성하여 처리하는 방법이 있다.


1. 예외(Exception)이 발생한 메소드 내에서 직접 처리 (try-catch-finally)


 

try{

    예외 발생 가능성이 있는 문장들;

}catch(예외 타입1 매개변수명){

    예외타입1의 예외가 발생할 경우 처리 문장들;

}catch(예외 타입 n 매개변수명){

    예외타입 n의 예외가 발생할 경우 처리 문장들;

}finally{

    항상 수행할 필요가 있는 문장들;

}


try 블록은 예외가 발생할 가능성이 있는 범위를 지정하는 블록이다. try 블록은 최소한 하나의 catch 블록이 있어야 하며, catch 블록은 try 블록 다음에 위치한다.

catch 블록의 매개변수는 예외 객체가 발생했을 때 참조하는 변수명으로 반드시 java.lang.Throwable 클래스의 하위 클래스 타입으로 선언되어야 한다.

지정된 타입의 예외 객체가 발생하면 try 블록의 나머지 문장들은 수행되지 않고, 자바 가상 머신은 발생한 예외 객체를 발생시키며 발생한 예외 객체 타입이 동일한 catch 블록을 수행한다.

finally 블록은 필수 블록은 아니다.
finally 블록이 사용되면 finally 블록의 내용은 예외 발생 유무나 예외 catch 유무와 상관 없이 무조건 수행된다. 따라서, 데이터베이스나 파일을 사용한 후 닫는 기능과 같이 항상 수행해야 할 필요가 있는 경우에 사용한다.

 

public class ExceptionTest {

    public static void main(String args[]){
       
        String[] name = new String[2];
       
        try{
            name[0] = "하이언";
            System.out.println("이름 : "+name[0]);
           
            name[1] = "아이유";
            System.out.println("이름 : "+name[1]);
           
            name[2] = "윤하";
            System.out.println("이름 : "+name[2]);
       
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("배열 참조 에러 발생");
        }catch(Exception e){
            System.out.println(e.getMessage());
        }finally{
            System.out.println("시스템 종료.");
        }
    }
}




- String[2] 배열을 선언하고, 3번째 배열에 값을 대입할 때, 예외가 발생한다.

- ArrayIndexOutOfBoundsException 이 발생하여 catch에 잡히고 "배열 참조 에러 발생" 이라는 메시지가 출력된다.

- 최종적으로 finally가 실행되며 "시스템 종료." 메시지가 출력된다.




2. 예외(Exception)이 발생한 메소드를 호출 한 곳으로 예외 객체를 넘기는 방법 (throws)


자바의 예외 처리 방법은 예외가 발생한 지점에서 try-catch 또는 try-catch-finally 블록을 이용하여 직접 처리하지 않아도 예외가 발생한 메소드를 호출한 지점으로 예외를 전달하여 처리하는 방법이 있다.


이때 사용하는 예약어가 throws 이다.


[modifiers] returnType name([argType argName, ...]) [throws exceptionName1, exceptionName2,...]


 

public class ExceptionTest {

    static void callDriver() throws ClassNotFoundException{
        Class.forName("oracle.jdbc.driver.OracleDriver");
        System.out.println("완료");
    }
   
    public static void main(String args[]){
       
        try{
           
            callDriver();
       
        }catch(ClassNotFoundException e){
            System.out.println("클래스를 찾을 수 없습니다.");
        }catch(Exception e){
            System.out.println(e.getMessage());
        }finally{
            System.out.println("시스템 종료.");
        }
       
    }
}


- main 함수에서 callDriver() 함수를 실행시킨다.

- callDriver() 함수에서는 "oracle.jdbc.driver.OracleDriver" 클래스를 가져온다.

- 해당 클래스를 찾지 못하면 ClassNotFoundException이 발생하는데, callDriver()에서는 throws ClassNotFoundException 처리로 호출한 main 함수로 예외를 넘긴다.

- main에서는 ClassNotFoundException을 받아 catch 문에서 잡아서 "클래스를 찾을 수 없습니다." 메시지를 출력한다.

- 마지막으로 finally가 실행되며 "시스템 종료" 를 출력한다.




3. 사용자 정의 예외 생성 (throw)


기존의 예외 클래스로 예외를 처리할 수 없다면 사용자만의 예외 클래스를 작성하여 발생시킬 수 있다.

사용자가 예외 클래스를 정의하려면 예외 클래스의 최상위 클래스인 java.lang.Exception 클래스를 상속받아 클래스를 정의한다.


class 예외 클래스 이름 extends Exception


자바 가상 머신은 프로그램 수행중에 예외가 발생하면 자동으로 해당하는 예외 객체를 발생시킨 다음 catch 블록을 수행한다.


하지만 예외는 사용자가 강제적으로 발생시킬 수도 있다. 자바는 예외를 발생시키기 위해 throw 예약어를 사용한다.


throw new 예외 클래스 이름(매개변수);


throw를 이용한 예외 발생시에도 try-catch-finally 구문을 이용한 예외 처리를 하거나, throws를 이용하여 예외가 발생한 메소드를 호출한 다른 메소드로 넘기는 예외 처리 방법을 사용해야 한다.


 

public class MyException extends Exception{
   
    public MyException(){
        super("내가 만든 예외");
    }
}

public class ExceptionTest {

    static void callException() throws MyException{
       
        throw new MyException();
    }
   
    public static void main(String args[]){
       
        try{
               callException();

       
              }catch(MyException e){
                      System.out.println(e.getMessage());
               }catch(Exception e){
                       System.out.println(e.getMessage());
               }finally{
                     System.out.println("시스템 종료.");
              }    
    }
}




- MyException 이라는 Exception을 상속한 예외를 만들었다. 그리고 MyException은 "내가 만든 예외" 라는 메시지를 갖는다.

- ExceptionTest의 main 함수가 실행되면 callException() 함수를 호출한다.

- callException 함수는 MyException()new로 생성한 후 callException() 함수를 호출한 main 함수로 던진다.

- MyException을 받은 main 함수는 catch에서 해당 예외를 받아서, 예외의 메시지를 출력한다. "내가 만든 예외"

- 최종적으로 finally가 실행되어 "시스템 종료"가 출력된다.



출처: https://hyeonstorage.tistory.com/203?category=557602 [개발이 하고 싶어요]