Skip to content

Commit 719d98a

Browse files
committed
feat(post): Add try-with-resources
1 parent f87583d commit 719d98a

File tree

1 file changed

+227
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)