728x90
자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다.
ex) InputStream, OutputStream, java.sql.Connection
코드 9-1 try-finally - 더 이상 자원을 회수하는 최선의 방책이 아니다!
// 코드 9-1 try-finally - 더 이상 자원을 회수하는 최선의 방책이 아니다! (47쪽)
static String firstLineOfFile(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
}
- 자원을 하나 더 사용한다면?
코드 9-2 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다!
// 코드 9-2 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다! (47쪽)
static void copy(String src, String dst) throws IOException {
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 {
in.close();
}
}
- 예외는 try 블록과 finally 블록 모두에서 발생할 수 있다
- 예외) 기기에 물리적인 문제가 생긴다면 firstLineOfFile 메서드 안의 readLine 메서드가 예외를 던지고
같은 이유로 close 메서드도 실패한다, 그러면 두 번째 예외가 첫 번째 예외를 집어삼켜 버린다
스택 추적 내역에 첫 번째 예외에 관한 정보는 남지 않게 되고 디버깅을 어렵게 만든다
이러한 문제는 자바7의 try-with-resources 덕에 모두 해결되었다
코드 9-3 try-with-resources - 자원을 회수하는 최선책!
// 코드 9-3 try-with-resources - 자원을 회수하는 최선책! (48쪽)
static String firstLineOfFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(
new FileReader(path))) {
return br.readLine();
}
}
코드 9-4 복수의 자원을 처리하는 try-with-resources - 짧고 매혹적이다!
// 코드 9-4 복수의 자원을 처리하는 try-with-resources - 짧고 매혹적이다! (49쪽)
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);
}
}
- try-with-resources 버전이 짧고 읽기 수월하며 문제를 진단하기도 훨씬 좋다
- firstLineOfFile 메서드를 생각해보면 reamLine과 close 호출 양쪽에서 예외가 발생하면,
close에서 발생한 예외는 숨겨지고 readLine에서 발생한 예외가 기록된다
- try-finally에서처럼 try-with-resources에서도 catch 절을 쓸 수 있다
코드 9-5 try-with-resources를 catch 절과 함께 쓰는 모습
// 코드 9-5 try-with-resources를 catch 절과 함께 쓰는 모습 (49쪽)
static String firstLineOfFile(String path, String defaultVal) {
try (BufferedReader br = new BufferedReader(
new FileReader(path))) {
return br.readLine();
} catch (IOException e) {
return defaultVal;
}
}
꼭 회수해야 하는 자원을 다룰 때는 try-finally 말고, try-with-resources를 사용하자
예외는 없다. 코드는 더 짧고 분명해지고, 만들어지는 예외정보도 훨씬 유용하다
try-finally로 작정하면 실용적이지 못할 만큼 코드가 지전분해지는 경우라도
try-with-resources는 정확하고 쉽게 자원을 회수할 수 있다.
728x90
'Books > Effective-Java 3판' 카테고리의 다른 글
10.equals는 일반 규약을 지켜 재정의하라(2) (0) | 2021.09.29 |
---|---|
10.equals는 일반 규약을 지켜 재정의하라(1) (0) | 2021.09.28 |
8.finalizer와 cleaner 사용을 피하라 (0) | 2021.09.25 |
7.다 쓴 객체 참조를 해제하라 (0) | 2021.09.24 |
6.불필요한 객체 생성을 피하라 (0) | 2021.09.23 |