JAVA

try-catch block에서 finally 블록이 필요한 이유

쿠카이든 2024. 4. 16. 00:40
728x90
컴파일할 때는 문제가 없던 프로그램도 동작 도중에 종종 오류가 발생한다. 사용자가 항상 개발자의 생각대로 프로그램을 사용하지 않기 때문이다. 숫자만 입력해야하지만 문자열을 입력하기도 하고, 파일을 업로드하기 전 파일의 이름을 지정하지 않기도 한다.

 

  •  이럴 때 발생하는 오류를 사전에 방지하는 것은 중요하다. 그런데 개발자가 이러한 오류가 발생할 때마다 프로그램이 종료되는 것을 원치 않을 수 있다. 오류를 무시하고 싶을 수도 있고, 그 오류가 발생 했을 때 수행할 적절한 동작을 직접 정의하고 싶을 수도 있다. 이럴 때 활용하는 것이 try-catch-finally 구문이다.
public class Main {
  
    public static void main(String[] args) {
  
        int [] arr = new int [3];
        try{
  
            System.out.println(arr[3]);
            System.out.println(arr[2]);
        } catch (ArrayIndexOutOfBoundsException e) {
  
            System.out.println("오류 발생!");
        } finally {
  
            System.out.println("finally...");
        }
    }
}
 
  •  위의 예제를 살펴보자 크기가 3인 int 배열을 선언했는데, index 3에 접근을 시도했다. 이 경우, JVM은 ArrayIndexOutOfBoundsException을 발생할 것이다. catch의 역할은 지정한 오류(Exception)이 발생할 경우의 동작을 정의할 수 있도록 도와준다. finally는 try와 catch구문이 끝났을 때 할 동작을 정의할 수 있는 키워드이다. 즉, 위 소스코드의 동작 결과는 아래와 같다.

 

1
2
오류 발생!
finally...
cs

 

728x90
  •  한편, 이러한 try-catch-finally block을 오류가 발생할 만한 모든 구역에 각각 구현하는 것은 조금 번거로운 작업이다. 그래서 throws라는 예약어를 사용하기도 한다. throw는 해당 메소드를 호출한 곳으로 발생한 Exception을 전달한다.(던진다) 아래 예제를 참고하자.
public class Main {
  
    public static void main(String[] args) {
  
        int [] arr = new int [3];
        try {
  
            customFunction(arr);
        } catch (ArrayIndexOutOfBoundsException e) {
  
            System.out.println("Exception 발생!");
        }
    }
  
    public static void customFunction (int [] arr) throws ArrayIndexOutOfBoundsException {
  
        System.out.println("함수 호출!");
        System.out.println(arr[5]);
    }
}
 
  •  18번째 줄에서 Exception이 발생했으나, try-catch block 대신, throws를 활용하여 main 메소드에 Exception을 전달했다. 그리고 main 함수에서 예외처리를 진행한다. 이를 활용하면 여러 메소드에서 발생할 수 있는 Exception을 한군데에서 처리할 수 있다. 위 소스코드의 실행 결과는 아래와 같다.

 

1
2
함수 호출!
Exception 발생!
cs

 

  •  try block에서 자원을 할당하는 로직이 있을 경우, Exception이 발생했을 때 자원이 제대로 해제되지 않을 수 있다. catch block 내부에 자원 해제를 구현하는 방법도 있지만,  finally block은 try와 catch의 결과에 상관없이 무조건 실행하는 부분이므로 자원의 해제 로직을 주로 finally에 구현한다. 
public class Main {
  
    public static void main(String[] args) {
  
        InputStream is = null;
        OutputStream os = null;
         
        try {
  
            is = new FileInputStream("fileName");
            os = new FileOutputStream("fileName");
        } catch (FileNotFoundException e) {
  
            System.out.println("파일이 없어서 Exception 발생!");
        } finally {
  
            try {
  
                is.close();
                os.close();
            } catch (IOException e) {
  
                System.out.println("자원 해제 도중 Exception 발생");
            }
             
        }
    }
}

 

참고: https://preamtree.tistory.com/84

 

[JAVA] try-catch-finally 구문(block)에 대한 소개

컴파일할 때는 문제가 없던 프로그램도 동작 도중에 종종 오류가 발생한다. 사용자가 항상 개발자의 생각대로 프로그램을 사용하지 않기 때문이다. 숫자만 입력해야하지만 문자열을 입력하기

preamtree.tistory.com

 

728x90