이번장의 핵심은...
꼭 회수해야 하는 자원을 다룰 때는 try-finally 말고,
try-with-resources를 사용하자
코드는 더 짧고 분명해지고, 만들어지는 예외 정보도 훨씬 유용하다
자원회수를 finalizer로? No!
자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다
Ex) InputStream, OutputStream, java.sql.Connection 등
자원 닫기를 놓칠 경우, 예측할 수 없는 성능 문제로 이어지기도 한다
상당 수가 안전망으로 finalizer를 활용하고 있지만 finalizer는 좋지 않다
자세한 내용은 아래에 정리해두었다
https://jackjeong.tistory.com/17
try-finally
전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였다
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 블록 모두 발생할 수 있는데, 한 예외가 다른 예외를 집어삼킬 수 있다
try-with-resources
이러한 문제들은 자바 7의 try-with-resources로 해결할 수 있다
이 구조를 사용하려면 해당 자원이 AutoCloseable 인터페이스를 구현해야 한다
만약 닫아야 하는 자원을 뜻하는 클래스를 작성한다면, 꼭 AutoCloseable을 구현하자
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로 변경하였다
훨씬 짧고 읽기 수월할 뿐 아니라 문제를 진단하기도 좋다
catch 절도 쓸 수 있어서 try 문을 중첩하지 않고도 다수의 예외를 처리할 수 있다
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (IOException e) {
return defaultVal;
}
'Java > Effective Java 3E' 카테고리의 다른 글
[이펙티브자바 3판] ITEM11. equals를 재정의하려거든 hashCode도 재정의하라 (0) | 2020.09.12 |
---|---|
[이펙티브자바 3판] ITEM10. equals는 일반 규약을 지켜 재정의하라 (0) | 2020.09.11 |
[이펙티브자바 3판] ITEM8. finalizer와 cleaner 사용을 피하라 (0) | 2020.09.08 |
[이펙티브자바 3판] ITEM7. 다 쓴 객체 참조를 해제하라 (메모리 누수) (0) | 2020.09.07 |
[이펙티브자바 3판] ITEM6. 불필요한 객체 생성을 피하라 (0) | 2020.09.06 |
댓글