Skip to content

Commit acc781f

Browse files
committed
feat: try-with-resources 를 이용한 자원해제
1 parent f0eca10 commit acc781f

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed

posts/java/try-with-resources.mdx

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
title: "try-with-resources 를 이용한 자원해제"
3+
date: "2024-10-10"
4+
tags: ["Java"]
5+
summary: "Let’s explore how to manage and release resources using try-with-resources in Java."
6+
description: "try-with-resources 를 이용한 자원해제와 동작 방식에 대해서 알아보자."
7+
---
8+
9+
:::info
10+
Java 7 에서는 Try-With-Resources 라는 기능이 도입되었는데, 이 기능의 개념을 알아보고 효과적으로 사용하는 방법에 대해서 알아보자.
11+
:::
12+
13+
---
14+
15+
### try-with-resources ?
16+
17+
[Java 7 - try-with-resources](https://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html) 에서 새로 나온 기능인,
18+
`try-with-resources` 는 "_자동 리소스 관리_" 기능으로, 여기서 말하는 **리소스** 란, 파일, 네트워크 연결과 같은 것을 의미한다. <br />
19+
파일, 네트워크 연결과 같은 리소스는 사용하면 명시적으로 `close` 를 해야하는데, 이를 잊는 경우에는 리소스 누수가 발생하여 성능 문제로 이어질 수 있다. <br />
20+
21+
22+
:::note
23+
보통 `finally` 블록을 이용해서 자원 해제(close) 해왔었다.
24+
:::
25+
26+
`try-with-resources` 를 사용하면, 더 이상 리소스가 필요하지 않을 때, 자동으로 `close` 하여, 리소스 관리를 간소화할 수 있게 된다. <br />
27+
아래 코드를 보면 명시적으로 `finally` 블록에서 `BufferedReader``close` 하여 수동으로 자원 해제를 했었는데,
28+
29+
```java
30+
public class WithoutTryWithResources {
31+
public static void main(String[] args) {
32+
BufferedReader reader = null;
33+
try {
34+
reader = new BufferedReader(new FileReader("example.txt"));
35+
String line;
36+
while ((line = reader.readLine()) != null) {
37+
System.out.println(line);
38+
}
39+
} catch (IOException e) {
40+
e.printStackTrace();
41+
} finally {
42+
if (reader != null) {
43+
try {
44+
reader.close(); // 자원을 수동으로 해제
45+
} catch (IOException e) {
46+
e.printStackTrace();
47+
}
48+
}
49+
}
50+
}
51+
}
52+
```
53+
54+
`try-with-resources` 를 사용하게 되면, `try()` 구문에서 사용하는 리소스를 초기화하고, 별도의 `close` 구문 없이 자원이 해제 시킬 수 있다.
55+
56+
```java
57+
public class WithTryWithResources {
58+
public static void main(String[] args) {
59+
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
60+
String line;
61+
while ((line = reader.readLine()) != null) {
62+
System.out.println(line);
63+
}
64+
} catch (IOException e) {
65+
e.printStackTrace();
66+
} // 자원이 자동으로 해제됨
67+
}
68+
}
69+
```
70+
71+
:::note
72+
이 때, try() 에 있는 자원은 <b>AutoCloseable</b> 을 구현한 객체여야 한다.
73+
:::
74+
75+
76+
---
77+
78+
### Q. 그러면 try-with-resources 는 어떻게 자원을 해제할까?
79+
80+
`try-with-resources``AutoCloseable` 인터페이스를 사용해서 구현되는데, 위 예시에서 사용한 `BufferedReader``Reader` 를 상속받고,
81+
`Reader``AutoCloseable` 를 상속한 `Closeable` 인터페이스를 구현한 클래스다.
82+
83+
`Reader``close()` 를 구현했기 때문에, `try-with-resources` 를 사용하면 별도의 자원 해제를 하지 않아도 자원이 해제된다.
84+
`Reader` 의 소스 일부를 보면 `close()` 메서드에서 자원을 닫는 것을 볼 수 있다.
85+
86+
```java
87+
public static Reader nullReader() {
88+
return new Reader() {
89+
private boolean closed = false;
90+
91+
// 중략 ...
92+
@Override
93+
public int read(char[] cbuf, int off, int len) throws IOException {
94+
Objects.checkFromIndexSize(off, len, cbuf.length);
95+
if (closed) {
96+
throw new IOException("Stream closed");
97+
}
98+
return -1; // null reader 에서는 아무 것도 읽지 않음
99+
}
100+
101+
@Override
102+
public void close() {
103+
closed = true; // 자원을 닫음
104+
}
105+
};
106+
}
107+
```
108+
109+
`AutoCloseable``close()` 메서드를 구현하도록 강제하는 인터페이스인데, `BufferedReader`, `FileInputStream`, `Connection` 과 같은 클래스들은 모두 `AutoCloseable` 또는 `Closeable` 인터페이스를 구현한다.
110+
111+
:::note
112+
<b> AutoCloseable vs Closeable </b> <br /><br />
113+
AutoCloseable : close() 메서드를 반드시 구현해야하고, Exception 을 던질 수 있다. <br />
114+
Closeable : AutoCloseable 의 하위 인터페이스로 주로 I/O 클래스에서 사용되며, 명시적으로 IOException 을 던질 수 있다.
115+
:::
116+
117+
---
118+
119+
### try-with-resources 동작 방식
120+
121+
**1) 자원 생성**
122+
123+
- try() 괄호 안에 있는 자원 초기화
124+
125+
**2) 블록 실행**
126+
127+
- try 블록 안의 코드가 실행
128+
129+
**3)️ 자원 해제**
130+
131+
- try 블록이 끝나거나, 예외가 발생하면, close() 메서드가 자동으로 호출
132+
- try 블록 내에서 예외가 발생하고, close() 메서드에서도 예외가 발생하는 경우
133+
- 첫 번째 예외는 발생한 예외로 처리되고, close() 에서 발생한 예외는 suppressed exception 으로 저장되고 Throwable.getSuppressed() 를 통해 확인 가능하다.
134+
135+
---
136+
137+
### AutoCloseable vs Closeable
138+
139+
140+
|구분|AutoCloseable|Closeable|
141+
|--|--|--|
142+
|도입시기|Java 7|Java 5|
143+
|예외처리|어떤 종류의 예외도 던질수 있음|`IOException` 만 던질 수 있음|
144+
|용도|다양한 자원 처리|주로 I/O 리소스 처리|
145+
146+
**1) AutoCloseable**
147+
148+
- Java 7 에서 도입된 인터페이스
149+
- **어떤 종류의 예외(Exception)** 도 던질 수 있다.
150+
- 모든 리소스를 처리할 수 있으며, I/O 관련 리소스 뿐만 아니라 다양한 자원에서 사용된다.
151+
- `try-with-resources` 구문에서 리소스를 자동으로 닫을 수 있도록 해주는 기본 인터페이스
152+
153+
**2) Closeable**
154+
155+
- Java 5 에서 도입된 인터페이스로, `AutoCloseable` 의 하위인터페이스
156+
- **IOException** 을 던질수 있도록 제한됨
157+
- I/O 스트림을 닫기 위한 목적으로 만들어짐
158+
159+
160+
---
161+
162+
### try-with-resources 의 이점
163+
164+
**1) 단순성**
165+
166+
- `try-with-resources``try-catch-finally` 블록을 사용하는 것보다 더 간결하고 읽기 쉽게 만든다.
167+
168+
**2) 자동 종료**
169+
170+
- 예외가 발생하더라도 리소스가 항상 적절하게 해제되도록 보장하여 리소스 누출 가능성을 줄여준다.
171+
172+
**3) 향상된 코드 품질**
173+
174+
- `finally` 블록에서 리소스를 닫는 등의 보일러플레이트 코드가 필요 없게 된다.
175+
176+
**4) 오류처리**
177+
178+
- 같은 블록 내에서 예외를 직접 잡을 수 있기 때문에 예외 처리가 더 간결하다.
179+
180+
181+
<br />
182+
183+
:::success
184+
💡 <b>정리</b><br />
185+
try-with-resources 를 이용하면 AutoCloseable 인터페이스를 구현한 자원들은 try() 구문에서 자동으로 close() 된다. <br />
186+
finally 블록 없이 간결한 코드를 작성할 수 있고, 리소스 누출 가능성을 줄일 수 있다. <br />
187+
:::
188+
189+
190+
---
191+
192+
### 📚 Reference
193+
194+
* [How To Use Try With Resource In Java Exception Handing](https://medium.com/thefreshwrites/how-to-use-try-with-resource-in-java-9c0b4ae48d21)
195+
* [Try-With-Resources In Java: Simplifying Resource Management](https://medium.com/@reetesh043/using-try-with-resources-in-java-simplifying-resource-management-bd9ed8cc8754)
196+
* [Java – Try with Resources](https://www.baeldung.com/java-try-with-resources)
197+
* [Java try-with-resources examples](https://www.codejava.net/java-core/the-java-language/using-try-with-resources-examples-java-7)
198+
* [How To Write Better Java with Try-With-Resources](https://thecodinginterface.com/blog/java-try-with-resources/)
199+
200+
<br/><br/>

0 commit comments

Comments
 (0)