코드를 작성하다 보면 예외처리를 위해 try-catch 구문을 굉장히 많이 사용 한다.
그러다 특별한 경우에 finally를 사용하게 되는데 만약 이 세 곳에 다 return 값이 있다면?
어떤 구문에 있는게 반환이 될까?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
String word = "a";
try {
word = "try";
System.out.println(word);
return word;
} catch (Exception e) {
word = "catch";
System.out.println(word);
return word;
} finally {
word = "finally";
System.out.println(word);
return word;
}
|
cs |
위와 같은 경우라면 콘솔에는 아래와 같이 출력이 된다.
try
finally
최종 리턴값 : finally
여기서 finally의 return을 주석처리하면 아래와 같이 출력이 된다.
try
finally
최종 리턴값 : try
finally에서 word의 값을 바꿨다고 해도 try에서 return 값은 다른 레퍼런스에 복사가 된 상태이기 때문에 실제 return 값은 try가 된다.
( try -> 리턴값 저장 -> finally -> 저장된 리턴값 반환)
finally에 return 이 있는 상태라면 어떻게 될까?
try 보다 후순위인 finally에 return 구분이 들어있기 때문에 return 값은 finally의 값이 된다.
(try -> 리턴값 저장 -> finally -> 새로운리턴구문 등장! -> 리턴값 저장 -> 저장된 리턴값 반환)
하지만 아래와 같은 경우라면 이야기가 다르다.
메모리에 직접 접근을 하는 경우인데 그 예가 배열 접근이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
String[] arr = {"apple","banana","orange"};
try {
arr[0] = "APPLE";
System.out.println(arr[0]);
return arr;
} catch (Exception e) {
arr[1] = "BANANA";
System.out.println(arr[0]);
return arr;
} finally {
arr[2] = "ORANGE";
System.out.println(arr[0]);
}
|
cs |
방금까지 본 예상으로라면 return 결과는
APPLE, banana, orange 가 출력이 되어야 할 것 같지만 실제로는 그렇지 않다.
APPLE, banana, ORANGE 가 출력이 되는 모습을 볼 수 있다.
try-catch 구문에 return 값이 존재한다면 finally 에서는 기본자료형, 참조자료형에 따라 return 값에 영향을 줄 수도 있고 아닐 수도 있기 때문이다.
배열같은 경우는 메모리에 직접 접근해서 값을 변경하기 때문에 위와같은 원하지 않는 return값이 발생할 수 있다. 이런 경우 때문에 finally에서 return 을 하는건 굉장히 조심해야 한다.
1. try 블록에서의 return
- try 리턴값 리턴
2. catch 블록에서의 return
- catch 리턴값 리턴
3. finally 블록에서의 return
- try-catch 에서 Exception이 발생을 해도 return의 제어권은 finally가 가져가게 됨. 오류인 상황이 발생을 해야 하지만 정상적으로 값이 전달 된 것으로 처리.
- 위와 같은 경우 때문에 finally에서 return을 사용하면 안된다!! (핵심)
최근댓글