Java try-catch-finally 흐름 완벽 이해하기
Java 예외 처리에서 가장 기본이면서도,
실무에서는 의외로 많은 개발자가 정확히 이해하지 못하는 것이 바로:
try-catch-finally 흐름
입니다.
특히:
- finally는 언제 실행되는가?
- return과 finally 충돌 시?
- 예외 재전파는 어떻게 되는가?
- JVM은 예외를 어떻게 처리하는가?
- suppressed exception은 무엇인가?
같은 부분은 실무 디버깅에서 매우 중요합니다.
이번 글에서는:
- try-catch-finally 실행 흐름
- Stack Unwinding
- finally 실행 보장
- return 충돌
- throw 충돌
- suppressed exception
- 실무 예외 처리 패턴
까지 깊게 정리해보겠습니다.
1. try-catch-finally란?
Java 예외 처리 기본 구조.
2. 기본 형태
try {
} catch(Exception e) {
} finally {
}
3. 역할
| 블록 | 역할 |
| try | 예외 발생 가능 코드 |
| catch | 예외 처리 |
| finally | 무조건 실행할 코드 |
4. 가장 기본 흐름
try {
System.out.println("A");
} catch(Exception e) {
System.out.println("B");
} finally {
System.out.println("C");
}
5. 예외 없으면?
실행 순서:
A
C
6. 예외 발생하면?
try {
throw new RuntimeException();
} catch(Exception e) {
System.out.println("catch");
} finally {
System.out.println("finally");
}
7. 실행 결과
catch
finally
8. finally 핵심 특징
매우 중요합니다.
finally는 거의 항상 실행된다
입니다.
9. 왜 finally가 중요할까?
대표 목적:
- 파일 close
- DB connection 반환
- lock 해제
- 리소스 정리
10. 예시
finally {
connection.close();
}
11. JVM 내부 흐름
매우 중요합니다.
예외 발생 시 JVM은:
Stack Unwinding
수행.
12. Stack Unwinding이란?
Stack unwinding 이란:
호출 스택을 되돌아가며 catch를 찾는 과정
입니다.
13. 예시 흐름
main()
↓
service()
↓
repository()
↓
예외 발생
↓
repository 종료
↓
finally 실행
↓
service 전달
↓
finally 실행
↓
main 전달
14. 매우 중요한 점
예외가 위로 전파되는 과정에서도:
finally는 실행됨
입니다.
15. finally가 실행 안 되는 경우
거의 없지만 존재.
16. 대표 예외 상황
| 상황 | finally 실행 |
| System.exit() | X |
| JVM 강제 종료 | X |
| OS 프로세스 kill | X |
| 치명적 JVM crash | X |
17. return과 finally
매우 중요합니다.
실무 면접 단골.
18. 예시
public int test() {
try {
return 1;
} finally {
System.out.println("finally");
}
}
19. 결과
finally 출력 후 return
즉:
return 전에 finally 실행
됩니다.
20. 왜 그럴까?
JVM이 내부적으로:
return 값 임시 저장
↓
finally 실행
↓
실제 return
흐름 수행.
21. 더 위험한 경우
finally 안에 return 존재.
22. 예시
public int test() {
try {
return 1;
} finally {
return 2;
}
}
23. 결과는?
2
24. 왜 위험할까?
finally의 return이:
기존 return 덮어씀
입니다.
25. 예외도 덮어쓸 수 있음
매우 위험.
26. 예시
try {
throw new RuntimeException();
} finally {
return;
}
27. 결과
예외 사라짐
28. 왜 문제일까?
디버깅 지옥 가능.
즉:
실제 오류 숨김
발생.
29. 실무 핵심 원칙
매우 중요.
finally 안에서 return 금지
입니다.
30. finally 안에서 throw도 위험
예시:
try {
throw new RuntimeException("A");
} finally {
throw new RuntimeException("B");
}
31. 결과
B만 보일 수 있음
32. 원래 예외 A는?
사라질 수 있음.
즉:
원인 손실
가능.
33. 이것이 try-with-resources 등장 이유 중 하나
매우 중요합니다.
34. try-with-resources
try (
BufferedReader br = ...
) {
}
35. 목적
리소스 자동 close
입니다.
36. close 중 예외 문제 해결
기존 finally 방식:
원래 예외가 close 예외에 덮임
가능.
37. suppressed exception 등장
Suppressed exception 이란:
원래 예외를 보존하면서 추가 예외 기록
하는 기능.
38. 예시 흐름
원래 예외 발생
↓
close() 중 추가 예외
↓
원래 예외 유지
↓
추가 예외 suppressed 저장
39. 확인 방법
exception.getSuppressed()
40. 왜 중요할까?
원인 추적 가능성 증가.
41. catch 순서도 중요
매우 중요합니다.
42. 안 좋은 예
catch(Exception e)
catch(IOException e)
43. 왜 문제일까?
상위 타입이 먼저 잡음.
즉:
하위 catch unreachable
컴파일 오류.
44. 올바른 순서
구체적인 예외
↓
더 큰 범위 예외
순.
45. multi-catch
Java 7 이후 가능.
46. 예시
catch(IOException | SQLException e)
47. finally와 변수 변경
예시:
int x = 1;
try {
return x;
} finally {
x = 2;
}
48. 결과는?
1 반환
49. 왜?
return 값은 이미:
임시 저장
되었기 때문.
50. 객체는 다를 수 있음
예시:
List<String> list =
new ArrayList<>();
try {
return list;
} finally {
list.add("A");
}
51. 결과
[A]
포함 가능.
왜냐하면:
참조 객체 자체 수정
했기 때문.
52. 실무에서 자주 하는 실수
1) finally에서 return
예외 삼켜질 수 있음.
2) catch(Exception) 남용
원인 분석 어려움.
3) 리소스 close 누락
메모리 누수 가능.
4) try-with-resources 안 사용
현대 Java에선 비효율적.
53. 실무 권장 패턴
현대 Java에서는 보통:
try-with-resources
우선 사용.
54. 이유
- close 자동 처리
- suppressed exception 지원
- 코드 간결
- 예외 보존 개선
55. 핵심 흐름 요약
예외 발생
↓
Stack Unwinding
↓
finally 실행
↓
catch 탐색
↓
처리 or 전파
56. 가장 중요한 핵심 한 줄
finally는 “거의 항상 실행”되지만,
finally 안의 return/throw는 기존 예외 흐름을 깨뜨릴 수 있다
입니다.
57. 정리
try-catch-finally는 단순 문법이 아닙니다.
실제로는:
- JVM Stack Unwinding
- 예외 전파
- suppressed exception
- 리소스 관리
- return 흐름 제어
전체와 연결되는 Java 핵심 실행 메커니즘입니다.
특히 실무에서는:
- finally return 금지
- try-with-resources 사용
- catch 순서
- 예외 보존
- Stack Trace 유지
를 정확히 이해하는 것이 매우 중요합니다.
다음 글에서는:
try-with-resources 원리
를 AutoCloseable, suppressed exception 내부 구조, close 순서, JDBC/IO 실무 패턴까지 포함해서 깊게 정리해보겠습니다.
'language > java' 카테고리의 다른 글
| Java 커스텀 예외(Custom Exception) 설계 완벽 이해하기 (1) | 2026.05.29 |
|---|---|
| Java try-with-resources 원리 완벽 이해하기 (0) | 2026.05.29 |
| Java Checked vs Unchecked Exception 완벽 이해하기 (0) | 2026.05.28 |
| Java Exception 구조 완벽 이해하기 (0) | 2026.05.28 |
| Java 함수형 프로그래밍 패러다임 이해 완벽 정리 (0) | 2026.05.28 |
댓글