Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 문자열
- Kotlin
- 구현
- mst
- swea
- 세그먼트 트리
- dfs
- 위상정렬
- 동적계획법
- JUnit 5
- 알고리즘
- java
- 그리디
- Effective Java
- 완전탐색
- 플로이드-와샬
- Network
- 프로그래머스
- 백준
- 스택
- 에라토스테네스의 체
- 시뮬레이션
- 수학
- 후니의 쉽게 쓴 시스코 네트워킹
- 투 포인터
- CS
- 백트래킹
- 이분탐색
- 유니온 파인드
- BFS
Archives
반갑습니다!
[Effective Java] 아이템 9: try-finally 보다는 try-with-resources를 사용하라 본문
- Java 라이브러리에는
close
메서드를 호출해 직접 닫아줘야 하는 자원이 많음 - ex)
InputStream
,OutputStream
,java.sql.Connection
- 이런 자원 중 상당수가 안전망으로
finalize
를 활용하고 있지만 그리 믿을만하지 않음(아이템 8)
- 이런 자원 중 상당수가 안전망으로
전통적인 방법
- 전통적으로 자원을 제대로 닫힘을 보장하기 위해 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 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
메서드도 실패함 - 이런 상황이라면 두 번째 예외가 첫 번째 예외를 완전히 집어삼켜서 스택 추적 내역에 첫 번째 예외 관련 정보는 남지 않아 디버깅이 어려움
- 기기에 물리적인 문제가 생긴다면
개선된 방법
- Java 7에 try-with-resources 가 이 문제를 해결해줌
- 이 구조를 사용하려면 해당 자원이
AutoCloseable
인터페이스를 구현해야함void
를 반환하는close
메서드 하나만 정의된 인터페이스- 닫아야 하는 자원을 뜻하는 클래스를 작성한다면
AutoCloseable
을 반드시 구현할 것
- 이 구조를 사용하려면 해당 자원이
static String firstLineOfFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(
new FileReader(path))) {
return br.readLine();
}
}
- 첫 번째 코드에 적용한 예시
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
메서드의readLine
과 (코드에는 나타나지 않는)close
호출 양쪽에서 예외가 발생하면,close
에서 발생한 예외는 숨겨지고readLine
에서 발생한 예외가 기록됨- 숨겨진 예외들은 스택 추적 내역에 '숨겨졌다(suppressed)'로 출력됨
catch 절
- try-finally에서처럼 try-with-resources에서도 catch 절을 사용할 수 있음
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로는 정확하고 쉽게 자원을 회수할 수 있음
'개발' 카테고리의 다른 글
[Effective Java] 아이템 11: equals를 재정의하려거든 hashCode도 재정의하라 (0) | 2021.08.03 |
---|---|
[Effective Java] 아이템 10: equals는 일반 규약을 지켜 재정의하라 (0) | 2021.07.29 |
[Effective Java] 아이템 8: finalizer와 cleaner 사용을 피하라 (0) | 2021.07.26 |
[Effective Java] 아이템 7: 다 쓴 객체 참조를 해제하라 (0) | 2021.07.25 |
[Effective Java] 아이템 6: 불필요한 객체 생성을 피하라 (0) | 2021.07.25 |