-
아이템9. try-finally 보다 try-with-resources 를 사용하라.Java/이펙티브 자바 2023. 6. 7. 10:17
핵심정리
- try-finally 는 더이상 최선의 방법이 아니다. (자바7부터)
- try-with-resources를 사용하면 코드가 더 짧고 분명하다.
- 만들어지는 예외 정보도 훨씬 유용하다.
static String firstLineOfFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } }
문제 1. try-finally
static void copy(String src, String dst) throws IOException { InputStream in = new FileInputStream(src); 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 { in.close(); // 여기서 에러 out.close(); } }
- out.close가 실행이 안될 수 도 있다.
문제 2. try-finally
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(); } }
- 코드에는 문제가 없지만, 코드가 너무 지저분하다.
문제 3. try-finally
public class TopLine { // 코드 9-1 try-finally - 더 이상 자원을 회수하는 최선의 방책이 아니다! (47쪽) static String firstLineOfFile(String path) throws IOException { BadBufferedReader br = new BadBufferedReader(new FileReader(path)); try { return br.readLine(); // CharConversionException } finally { br.close(); // StreamCorruptedException } } public static void main(String[] args) throws IOException { System.out.println(firstLineOfFile("pom.xml")); // 가장 나중에 발생한 예외인 StreamCorruptedException 가 보인다. } }
- 가장 처음의 발생한 예외를 알 수 없다.
- try-with-resources 를 사용한다면 두 가지 예외 순서대로 다 보인다.
해결 방안1. 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); } } }
- catch 문이나 finally 문도 사용 가능하다.
완벽공략
- p48, 자바 퍼즐러 예외 처리 코드의 실수
static void copy(String src, String dst) throws IOException { InputStream in = new FileInputStream(src); 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 { try { out.close(); } catch (IOException e) { // IOException 이 아니라 런타임ex이 터진다면 catch 문 X // TODO 안전한가? } try { in.close(); } catch (IOException e) { // TODO 안전한가? } } }
- p49, try-with-resources 바이트코드
ㆍ중첩된 try-catch 문을 사용
ㆍaddSuppressed 함수로 에러를 순서대로 담아줘서 출력 ( 첫번째 에러 보존 )
ㆍclose 함수를 여러번 호출 - idempotent
'Java > 이펙티브 자바' 카테고리의 다른 글
아이템11. equals를 재정의하려거든 hashCode도 재정의하라 (0) 2023.06.17 아이템10. equals는 일반 규약을 지켜 재정의하라 (0) 2023.06.07 아이템8. finalizer와 cleaner 사용을 피하라 (0) 2023.06.04 아이템7. 다 쓴 객체 참조를 해제하라. (0) 2023.06.01 아이템6. 불필요한 객체 생성을 피하라 (0) 2022.11.10