728x90
자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다.(InputStream, OutputStream, java.sql.Connection 등)
자원 닫기는 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어지기도 한다.
안전망으로 fianlizer를 활용하기도 하지만 믿을만하지 못하다.(아이템 8)
전통적인 자원 닫힘 보장 수단 : try-finally
단점
- 자원이 둘 이상이면 코드가 지저분해진다.
- 두 번째 예외가 첫 번째 예외를 집어삼켜 버려 스택 추적 내역에 첫 번째 예외 정보는 남지 않게 되고, 디버깅을 어렵게 한다.
- 아래 firstLineOfFile 메서드의 br.readLine()에서 예외가 발생하고, br.close() 실패하면 두 번째 예외가 첫 번째 예외를 삼켜버린다.
static String firstLineOfFile(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
}
(자바 7) 자원을 회수하는 최선책 : try-with-resources
- 이 구조를 사용하려면 단순히 void close() 메서드 하나만 정의되어있는 AutoClosable 인터페이스를 구현해야 한다.
- try블록을 벗어날 때 자동으로 close() 메서드가 호출된다.
- try를 중첩하지 않고도 다수의 예외를 처리할 수 있다.
- 숨겨진 예외들도 버려지지 않고, 스택 추적 내역에 '숨겨졌다(suppressed)'는 꼬리표를 달고 출력된다.
- 자바 7의 Throwable에 추가된 getSuppressed 메서드를 사용하면 숨겨진 예외를 배열 형태로 받아올 수 있다.
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-finally 말고, try-with-resources를 사용하자
'책읽고 정리 > Effective Java' 카테고리의 다른 글
[Effective Java 3/E] 아이템7. 다 쓴 객체 참조를 해제하라 (0) | 2021.06.22 |
---|---|
[Effective Java 3/E] 아이템6. 불필요한 객체 생성을 피하라 (0) | 2021.06.10 |
[Effective Java 3/E] 아이템5. 자원을 직접 명시하지 않고 의존 객체 주입을 사용하라 (0) | 2021.05.29 |
[Effective Java 3/E] 아이템4. 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2021.05.25 |
[Effective Java 3/E] 아이템3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2021.05.24 |
댓글