티스토리 뷰

 

try catch 구문에서 finally는 예외가 발생 여부와 관계없이 반드시 처리해야 할 때 사용된다. 예를 들어 보자. catch와 finally를 같이 쓸 때는 try 블록에서 리소스를 얻어 사용하고, catch 블록에서는 예외적인 상황을 다루며, finally 블록에서는 리소스를 해제한다.

public class TryCatchFinally {

    public static void main(String[] args) {
        System.out.println("getReturn : " + getReturn());
    }
    
    static String getReturn() {
        
        String str = "do";
        
        try {
            
            str = "Try";
            System.out.println(str);
            return str;
            
        } catch (Exception e) {
            
            str = "Catch";
            System.out.println(str);
            return str;
            
        } finally {
            
            str = "Finally";
            System.out.println(str);
            //return str;
        }
    }
}

왼쪽은 finally에서 return문을 주석 처리하였을 때 결과이고, 오른쪽은 finally에서 return을 한경우이다.

finally에서 return은 매우 조심해야 한다. 실제 위와 같이 경고가 발생한다. 자칫 잘못하다가는 원하는 결과가 나타나지 않을 수도 있다.

 

이번에는 예외를 던져서 try catch finally 관계를 알아보자.

public class TryCatchFinally {

    public static void main(String[] args) {
        try {
            System.out.println("getThrowReturn : " + getThrowReturn());
        } catch (Exception e) {
            System.out.println("getThrowReturn Exception");
            e.printStackTrace();
        }
    }
    
    static String getThrowReturn() {
        
        String str = "do";
        
        try {
            
            str = "Try";
            System.out.println(str);
            throw new Exception("Try Exception");
            
        } catch (Exception e) {
            
            str = "Catch";
            System.out.println(str);
            throw e;
            
        } finally {
            
            str = "Finally";
            System.out.println(str);
            return str;
        }
    }
}

try 구문에서 Exception을 발생시켜 catch 구문에 도달하게 만들었다. 이후 throw를 통해 호출자에게 예외를 알렸고 finally에서 return이 이루어졌다. 결과를 한번 확인해 보자.

getThrowReturn를 호출한 main 함수에서 Exception이 발생해야 되는데 발생하지 않았다. 이번 이유 역시 fianlly에서의 return 때문이다.

 

이번에는 finally에서의 값 변경이 어떤 의미를 갖는지 알아보자.

public class TryCatchFinally {

    public static void main(String[] args) {
        String[] array = getArrayReturn();
        System.out.println(Arrays.toString(array));
    }
    
    static String[] getArrayReturn() {
        
        String[] strArray = {"Try", "Catch", "Finally"};
        
        try {
            
            strArray[0] = "Try!";
            System.out.println(strArray[0]);
            return strArray;
            
        } catch (Exception e) {
            
            strArray[1] = "Catch!";
            System.out.println(strArray[1]);
            return strArray;
            
        } finally {
            
            strArray[2] = "Finally!";
            System.out.println(strArray[2]);
            return strArray;
        }
    }
}

finally 구문에서 값을 변경하였을 때 자료형에 따라 값이 변하기도 변하지 않기도 한다. 첫 번째 예시 getReturn에서 기본자료형 값을 변경하였지만 return 값은 그래도 였다. 하지만 참조자료형의 경우 값이 변경되는 것을 볼 수 있다. try catch 구문에 return이 존재하면, 변수(값), 레퍼런스(참조 값)에 대한 복사가 이루어지는데 finally에서 기본자료형의 경우 새로운 변수 값, 참조자료형의 경우 레퍼런스 복사가 이루어지고 finally가 실행된다.

 

위에서 테스트한 코드를 바탕으로 요약하자면 아래와 같이 try catch finally을 이해해야 한다.

try 블록 안에 return
finally 블록 거쳐 정상종료

catch 블록 안에 return
finally 블록 거쳐 정상종료

finally 블록 안에 return
try 블록 안에서 발생한 Exception이 무시되고 finally 블록으로 제어가 전달되어 결국에는 정상종료(Exception이 발생하지 않은 것처럼 보일 가능성) 이러한 이유로 finally에서 return을 사용하면 안 된다.

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함