자바 close()? 그거 좀 귀찮네...
자바 하다 보면 꼭 마주치는 close(). InputStream, OutputStream, BufferedReader... 얘네 왜 이렇게 닫을 게 많은 걸까? 안 닫으면 뭐... 좀 곤란해진다.
왜 닫아야 하는지, 대충 요약하자면
- 자원 낭비:
- OS가 관리하는 애들이라 안 닫으면 언젠가 시스템이 맛이 갈 수도 있다.
- 데이터 유실:
- 버퍼에 있는 데이터는 사라질 수도 있고.
- 안전 문제:
- 예외 터져도 마무리는 해야 하지 않겠나?
- 예외 터져도 마무리는 해야 하지 않겠나?
그래서 뭐, 닫아야 한다고. 근데 왜 이렇게 말이 많은 거지?
개발자들이 자꾸 까먹고 안 닫는다. 그래서 문제가 생기는 거고.
옛날 방식, try-finally
예전엔 이걸로 해결했다.
static String firstLineOfFile(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
}
static void copy(String src, String dst) throws IOExeption () {
InputStream in = new FileInputStream(src);
try {
OutputStream out = new FileOutputStream(dst);
try {
byte[] buf = new byte [BUFFER_SIZE];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
} finally {
out.close();
}
} finally {
int.close();
}
}
첫 번째는 그나마 괜찮은데, 여러 개 닫아야 하면 코드가 좀... 그렇다. 그리고 예외가 겹치면 디버깅이 좀 귀찮아진다.
finally 에서의 예외가 try 예외를 삼킬 수도 있다고 한다.
요즘 방식, try-with-resources
자바 7부터 나온 건데, 이걸 쓰면 좀 편해진다.
static void copy(String src, String dst) throws IOException {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst)) {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}
}
보다시피 코드가 훨씬 깔끔해진다. 예외가 여러 개 터져도 알아서 처리해 준다.
static String firstLineOfFile(String path, String defaultVal) {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (IOExeptuin e) {
return defaultVal;
}
}
여기서 readLine과 보이지 않는 close 호출 양쪽에서 예외가 발생하면, close예외가 숨겨지고 readLine에서 발생한 예외가 기록된다고 한다.
결론
- 자원 관리는 필수. try-with-resources 쓰면 편하다. 꼭 쓰자.
- 예외 처리는 언제나 중요. 귀찮아도 하자.
'Learning > TIL' 카테고리의 다른 글
[250326] 코딩테스트 문제 해결을 위한 단계별 접근법 (Java 8 기반) (1) | 2025.03.26 |
---|---|
[250325] Aiven & 프로젝트 (1) | 2025.03.25 |
[250325] 자격증 (0) | 2025.03.25 |
도커(Docker)? (0) | 2025.03.13 |
Slack 이미지 전송 문제 해결: attachments에서 Block Kit으로 마이그레이션 (0) | 2025.03.04 |