반응형
Java try-with-resources 원리 완벽 이해하기
Java 7부터 도입된:
try-with-resources
는 현대 Java에서 파일, 네트워크, DB 연결 등을 다룰 때 거의 필수로 사용됩니다.
실무에서는:
- JDBC Connection
- PreparedStatement
- ResultSet
- FileInputStream
- BufferedReader
등을 처리할 때 대부분 사용합니다.
예:
try (
BufferedReader br =
new BufferedReader(
new FileReader("test.txt")
)
) {
System.out.println(br.readLine());
}
이 문법은 단순한 문법 설탕(Syntactic Sugar)이 아닙니다.
실제로는:
- AutoCloseable
- 컴파일러 코드 변환
- finally 자동 생성
- Suppressed Exception
까지 연결되는 중요한 JVM 동작 원리입니다.
1. 왜 등장했을까?
Java 6 이전에는:
BufferedReader br = null;
try {
br = new BufferedReader(
new FileReader("test.txt")
);
} finally {
if (br != null) {
br.close();
}
}
처럼 작성했습니다.
2. 문제점
매우 많았습니다.
코드가 길다
if (br != null)
반복.
close 누락 가능
connection.close();
실수로 빠뜨릴 수 있음.
예외 덮어쓰기 문제
매우 중요.
3. 예외 덮어쓰기 문제
예:
try {
throw new RuntimeException("원래 예외");
} finally {
throw new RuntimeException("close 예외");
}
4. 결과
close 예외만 보임
5. 문제
원래 예외가 사라짐.
즉:
진짜 원인 분실
발생.
6. 그래서 등장
Java 7:
try-with-resources
추가.
7. 기본 문법
try (
Resource resource = ...
) {
}
8. 특징
try 블록 종료 시
자동 close()
수행.
9. 어떤 객체가 가능할까?
매우 중요.
10. AutoCloseable
AutoCloseable 인터페이스 구현 필요.
11. 정의
public interface AutoCloseable {
void close() throws Exception;
}
12. 즉
implements AutoCloseable
만 하면 사용 가능.
13. 예시
class MyResource
implements AutoCloseable {
@Override
public void close() {
System.out.println("close");
}
}
14. 사용
try (
MyResource r = new MyResource()
) {
System.out.println("work");
}
15. 결과
work
close
16. 컴파일러 내부 변환
매우 중요합니다.
실제로 JVM에선:
try (
Resource r = ...
) {
}
를 직접 실행하지 않음.
17. 컴파일 후
대략 아래 코드로 변환.
Resource r = ...;
try {
} finally {
if (r != null) {
r.close();
}
}
18. 즉
컴파일러가 finally 생성
해주는 것.
19. close 실행 시점
순서:
try 실행
↓
정상 종료
↓
close()
20. 예외 발생 시
try 예외
↓
close()
↓
예외 전파
21. 여러 리소스 사용 가능
예:
try (
Connection conn = ...;
PreparedStatement ps = ...;
ResultSet rs = ...
) {
}
22. close 순서
매우 중요.
23. 생성 순서
conn
↓
ps
↓
rs
24. close 순서
반대.
rs
↓
ps
↓
conn
25. 왜 반대일까?
스택 구조 때문.
26. 비유
접시 쌓기
와 같음.
마지막에 올린 것부터 제거.
27. JDBC에서 중요한 이유
예:
ResultSet
은
PreparedStatement
에 의존.
28. 먼저 닫으면?
의존성 문제
발생 가능.
29. 그래서 역순 close
안전.
30. Suppressed Exception
매우 중요합니다.
31. 예시
try (
MyResource r = ...
) {
throw new RuntimeException("원래 예외");
}
32. close도 실패
public void close() {
throw new RuntimeException(
"close 실패"
);
}
33. 예전 finally 방식
close 실패만 보임
34. try-with-resources
원래 예외 유지
+
close 예외 보관
35. 이것이 Suppressed Exception
Suppressed exception
36. 구조
Main Exception
└─ Suppressed Exception
37. 확인 방법
Throwable[] suppressed =
e.getSuppressed();
38. 예시 출력
for (Throwable t :
e.getSuppressed()) {
System.out.println(
t.getMessage()
);
}
39. 왜 중요할까?
실제 장애 분석 시:
원래 예외
+
close 예외
둘 다 확인 가능.
40. JDBC 실무 예시
가장 흔한 패턴.
try (
Connection conn =
dataSource.getConnection();
PreparedStatement ps =
conn.prepareStatement(sql);
ResultSet rs =
ps.executeQuery()
) {
while (rs.next()) {
}
}
41. 장점
자동 close
42. 누수 방지
Connection Leak 감소
43. 코드 간결
finally 제거
44. 파일 처리도 동일
try (
BufferedReader br =
Files.newBufferedReader(path)
) {
}
45. 실무에서 자주 하는 실수
1) close 직접 호출
try-with-resources
안에서:
resource.close();
직접 호출.
불필요.
2) AutoCloseable 미구현
컴파일 오류.
3) close 예외 무시
Suppressed Exception 확인 안 함.
4) try 밖에서 리소스 생성
안 좋은 예:
Connection conn =
getConnection();
try(conn) {
}
가능은 하지만 보통 생성도 try 안에서.
46. Closeable vs AutoCloseable
많이 물어봄.
AutoCloseable
void close() throws Exception
Closeable
void close() throws IOException
47. 관계
AutoCloseable
↑
Closeable
48. Stream도 AutoCloseable
예:
Files.lines(path)
49. 그래서 가능
try (
Stream<String> stream =
Files.lines(path)
) {
}
50. 실무 핵심 규칙
매우 중요.
AutoCloseable 객체는
무조건 try-with-resources 우선
51. 핵심 흐름 요약
리소스 생성
↓
try 실행
↓
예외 여부 관계없이
↓
자동 close()
↓
예외 전파
52. 가장 중요한 핵심 한 줄
try-with-resources는
컴파일러가 finally + close 로직을 자동 생성하고,
Suppressed Exception까지 안전하게 처리하는 기능이다
53. 면접 단골 질문
Q. try-with-resources를 쓰려면 무엇을 구현해야 하나?
AutoCloseable
Q. 여러 리소스가 있으면 close 순서는?
생성 역순
Q. 왜 finally보다 좋은가?
Suppressed Exception 지원
+
누수 방지
+
코드 간결
다음 글에서는 "커스텀 예외(Custom Exception) 설계" 를 진행하면 지금까지 배운 Exception 구조, Checked/Unchecked, Spring RuntimeException 전략이 전부 연결되기 시작합니다. 실무에서 가장 많이 사용하는 예외 설계 패턴까지 함께 다룰 수 있습니다.
반응형
'language > java' 카테고리의 다른 글
| Java 예외 로그 전략 완벽 이해하기 (0) | 2026.05.29 |
|---|---|
| Java 커스텀 예외(Custom Exception) 설계 완벽 이해하기 (1) | 2026.05.29 |
| Java try-catch-finally 흐름 완벽 이해하기 (0) | 2026.05.29 |
| Java Checked vs Unchecked Exception 완벽 이해하기 (0) | 2026.05.28 |
| Java Exception 구조 완벽 이해하기 (0) | 2026.05.28 |
댓글