살군의 보조기억 장치

Another memory device…

try {} catch {} finally {} 구문 사용법 in Java

leave a comment »

갑자기 try catch finally 구문에 대한 궁금증이 생겼었는데… 좋은 포스팅을 찾아서 그대로 붙여봅니다… ㅋㅋ 젤 아래 원문에 대한 링크가 있으니 괜찮겠지요? ;;; 트랙백을 보내고 싶은데 어떻게 보내는지 몰라서 그냥 원문 주소  링크 겁니다.

OKJsp 사이트를 매일 같이 방문을 하면서 이런 저런 글들을 많이 봅니다. 개인적으로는 사는 얘기, 유머.. 그리고 TIP 등을 주로 보고, 시간이 될때는 Q&A를 보면서 답을 달기도 합니다.
서 두를 이렇게 꺼내는 이유는 질문 중에서 try…catch…finally에 대한 질문이 있어서 그렇습니다. “떡 본 김에 제사지낸다”는 속담이 이런 경우에 사용되는 것인지는 모르겠지만 이왕 질문을 본 김에 갑자기 떠오르는 생각에 테스트를 몇가지 해봤습니다.

아! 일단 try…catch…finally에서 fianlly의 구문은 언제나…반드시 실행이 됩니다. 즉

try
{
  return;
}
catch
{
  ......
}
finally
{
  ......
}

일 경우에도 finally 구문은 반드시 실행이 됩니다. 머… 이것이 질문의 내용이 었고요…

이것을 보고 갑자기 떠오른 생각이 두가지가 있었는데 다음과 같습니다.
1. try…finally 구문이 중첩되어 있을 경우.?
2. try…finally 구분이 있을 때 try 에서 return을 한 후에 finally에서 또 return을 하면.?
일단 1번에 대해서는 당연히 안쪽의 finally 구문이 먼저 실행 되고 바깥쪽의 finally 구문이 실행 될 것이라고 예상했습니다. 그리고 2번에 대해서는 당연히 try에서 리턴한 값이 리턴이 될 것이라고 예상을 했고요..

테스트 코드를 짜서 돌린 결과… 1번에 대한 예상은 맞았습니다. 그리고 2번에 대한 예상은…
헉! 허~~~억
예상과 다르게 나와 버렸습니다. 쩝… 물론 예상한 대로 나왔다면 이 포스트를 올리지 않았겠죠…^^;; ;ㅎㅎㅎ

예상과 다르게 finally 구문에서 리턴한 값이 최종적으로 리턴되었습니다.
실제 테스트 코드는 다음과 같습니다.

public class FinallyReturn
{
    public int test()
    {
        try
        {
            System.out.println("TRY");
            return 1;
        }
        finally
        {
            System.out.println("FINALLY");
            return 2;                       // ---- (1)
        }
    }
    
    public static void main(String args[])
    {
        FinallyReturn tester = new FinallyReturn();
        System.out.println(tester.test());
    }
}

그리고 그 결과는

TRY
FINALLY
2

로 나옵니다… 테스트 환경은 JDK 1.4.2_06 Window 버전이고 eclipse 3.0에서 테스트 코드를 만들어서 돌렸습니다. 그리고 당연히 (1) 부분을 빼버리면 리턴 값을 예상 대로 1이 나옵니다.

후우… 스스로 자바에 대해서는 어느정도 안다고 생각을 했었는데… 아직 멀었다는 생각을 해봅니다… 에혀…

어 쨌거나… 그래서 한번 스펙을 찾아 보니까 조금 복잡하게 되어 있기는 하지만… 스펙상으로는 문제가 없더군요… 머 의외긴 하지만… 특정한 상황에 대해서 몇가지 경우를 주고 선택이 가능한 것 같더군요… 그렇다는 얘기는 VM에 따라서 다르게 적용될 수도 있다는 얘기가 되니까 다른 Vendor의 JVM에서는 다를 수 있다는 말이 될 것 같습니다. ㅎㅎ 제 영어 실력은 상당히 낮기 때문에 신뢰 하지는 마십시요.
원문
If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:
– If the finally block completes normally, then the try statement completes abruptly for reason R.
– If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

=> 이부분을 다시 생각을 가다듬고 보니까… 제가 잘못 해석을 했다는 것이 드러나네요…^^;;; 실제 스펙상으로도 복잡하긴 하지만 명확하게 정의되어 있는 것이네요. 즉 위의 구문을 간략히 해석해 보면 “try 블럭이 뜻밖의 이유 R로 종료가 되렀을 경우에 Finally 구문은 다음의 두가지 선택이 있게 된다. 첫번째로 finally 구문이 정상적으로 종료가 된 경우에는 try 구문은 R이 이유로 종료가 된다. 두번째로 finally 구문이 뜻밖의 이유 S로 종료가 된 경우에는 try 구문은 S의 이유로 종료가 된다. 그리고 R은 버려진다.” 입니다. 즉 앞에서 얘기한 대로 VM에 따라서 다르게 적용 될 수 있는 것이 아니죠…

PS. 이 것은 예외에 있어서도 동일하게 적용이 되더군요…. try에서 예외를 발생을 시키고 다시 finally 구문에서도 예외를 발생시키면 최종적으로 발생하는 예외는 finally에서 발생시킨 예외가 던져집니다.

public class ExceptionFinally
{
    public int test()
    	throws Exception
    {
        try
        {
            System.out.println("TRY");
            throw new Exception("TRY EXCEPTION");
        }
        finally
        {
            System.out.println("FINALLY");
            throw new Exception("FINALLY EXCEPTION");
        }
    }
    
    public static void main(String args[])
    {
        ExceptionFinally tester = new ExceptionFinally();
        
        try
        {
            tester.test();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

결과 입니다.

TRY
FINALLY
java.lang.Exception: FINALLY EXCEPTION
at test.language.trycatch.ExceptionFinally.test(ExceptionFinally.java:36)
at test.language.trycatch.ExceptionFinally.main(ExceptionFinally.java:46)
 

retrieved from: http://skywatch.egloos.com/859503

Advertisements

Written by gomiski

2011/08/04 at 4:39 am

Posted in Java, Lecture

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: