본문 바로가기
Java의 정석/예외처리

예외처리 11 ~ 14 - 메서드에 예외 선언 하기, finally 블럭

by Hwanii_ 2023. 8. 27.
728x90
메서드에 예외 선언 하기, finally 블럭

메서드에 예외 선언 하기

- 예외를 처리 하는 방법 : try-catch 문, 예외 선언 하기.

try-catch 문 : 직접 처리 O.
예외 선언 하기 : 직접 처리 X. (떠넘기기 / 던지기)

- 메서드가 호출시 발생 가능한 예외를 "호출 하는 쪽" 에 알리는 것.

참고 :
예외 발생 키워드 : throw
예외를 메서드에 선언 하는 키워드 : throws

둘을 잘 구별 하기.

 

void method() throws Exception1, Exception2, .. ExceptionN {    //  메서드의 예외 선언 (throws 키워드 사용)
    //  메서드의 내용.
}

void method() throws Exception {    //  모든 종류의 예외가 발생 하는 것을 의미 하는 Exception (모든 예외의 최고 조상)
    //  메서드의 내용.
}

 

 

 

참고 :
오버라이딩
1.  선언부 일치.
2.  접근 제어자는 좁게 불가능.
3.  조상 보다 많은 예외 선언 불가능.

참고 :
Exception은 모든 예외의 최고 조상이고,
1개만 작성 되어 있어서,
예외를 여러개 선언한 메서드 보다, 적게 예외를 선언 한 것 처럼 보여지지만,
모든 예외의 최고 조상이기에, 던질 수 있는 예외의 개수가 모든 예외 클래스의 개수 이다.

 

finally  블럭

- 예외 발생 여부와 관계 없이 수행 되어야 하는 코드를 넣는다.

try {
    //  예외가 발생할 가능성이 있는 문장들을 넣기.
}
catch (Exception1 e1) {
    //  예외 처리를 위한 문장을 적기.
}
finally {
    //  예외의 발생 여부에 관계 없이 항상 수행 되어야하는 문장들을 넣기.
    //  finally 블럭은 try-catch 문의 맨 마지막에 위치.
}

 

 

 

예제 01)

 

class Ex8_9 {

    public static void main(String[] args) throws Exception {
        method1();  //  같은 클래스내의 static 멤버 이므로 객체 생성 없이 직접 호출 가능.

    }   //  main 메서드의 끝

    static void method1() throws Exception {
        method2();

    }   //  method1의 끝

    static void method2() throws Exception {
        throw new Exception();

    }   //  method2의 끝

}   // main class

//  예외를 던지고, 아무도 처리 하지 않았기 때문에, JVM 의 기본 예외 처리기가 출력 한다.
//  콘솔창에 출력되는 메세지는 예외가 발생 했을 때 당시 (호출 스택) 의 정보가 담겨져 있다.
//  정리하자면, 마지막에, main() 메서드도 예외를 처리 하지 않았기 때문에,
//  main() 메서드 호출이 끝나면서, 프로그램이 비정상 종료 되고,
//  최종적으로, JVM 이 받아서 처리 되지 않은 예외를 콘솔창에 출력.

 

예제 02)

 

import java.io.File;

class Ex8_10 {

    public static void main(String[] args) {
        try {
            File f = createFile("");   //   여기에 파일 이름을 작성.
            System.out.println(f.getName() + "파일이 성공적으로 생성되었습니다.");
        } catch (Exception e) {
            System.out.println(e.getMessage() + " 다시 입력해 주시기 바랍니다.");
        }
    }   //  main()

    static File createFile(String fileName) throws Exception {

        if (fileName == null || fileName.equals("")) {
            throw new Exception("파일이름이 유효하지 않습니다.");
        }

        File f = new File(fileName);    //  File 클래스의 객체를 만든다.

        f.createNewFile();  //  File 객체의 createNewFile() 메서드를 이용해서 실제 파일을 생성.

        return f;   //  생성된 객체의 참조를 반환.

    }   // createFile()

}    // main class

//  createFile() 메서드 내부에서 발생한 예외가 생기면,
//  그것을 이 메서드 내부에서 예외 처리를 직접 하는게 아니라,
//  throws 키워드를 사용 해서, 예외를 던졌다.
//  그러면, createFile() 메서드를 호출한 곳에서 예외를 받고,
//  여기서, 예외를 처리 해주면 된다.

//  만약에 createFile() 메서드 내부에, try-catch 로 예외를 잡으면,
//  main() 메서드는 예외가 발생한 사실 조차도 모르게 된다.

 

 

파일 이름을 위와 같이 "" (공백값) 으로 작성 하면,

 

 

일부러 예외를 생성 했다.

 

그러면 예외가 발생 하니까,

예외를 createFile() 메서드 내부에서 try-catch 를 통해서 직접 잡거나,

또는, throws 키워드로 createFile() 메서드를 호출한 쪽으로 던진다.

 

위의 이미지는 throws 키워드로 발생하는 모든 예외를 던지고 있는것을 확인 할 수 있다.

 

 

참고로, 파일명을 작성하고 파일을 생성 하면,

 

 

파일이 잘 생성 되는 것을 확인 할 수 있다.

 

++ 

 

 

일부러 만든 Exception 예외를 주석 처리 하고,

메서드에 달린 throws 키워드를 제거 하면,

 

 

createNewFile() 메서드가 작성 되어 있는 곳에서,

컴파일 에러가 발생 하는것을 확인 할 수 있다.

 

 

왜냐하면, 위와 같이, createNewFile() 메서드는 IOException 예외를 던지고,

(파일 입출력 예외)

 

이 IOException 예외의 부모 클래스는,

 

 

Exception 클래스 이다.

 

Exception 클래스는 예외 처리 또는 예외 던지기를 반드시 명시해 줘야,

컴파일 에러가 나지 않는다.

반응형