try-finally 대신 try-with-resources를 사용하라
자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많은데, 클라이언트가 닫는 것을 놓치기 쉬워 안전망으로 이전 아이템에서 언급했던 finalizer를 활용하고 있다. 하지만 이는 문제가 많아 전통적으로 try-finally가 쓰였다.
public static String firstLineOfFile(String path) throw IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
}
위의 코드에서 readLine() 코드가 예외를 던지고, 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();
}
}
지저분해지기도 한다.
이러한 문제들은 자바7
에서 나온 try-with-resources로 해결할 수 있다. (AutoCloseable를 구현한 객체에 대해서만 사용할 수 있다.)
public static String firstLineOfFile(String path) throw IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (Exception e) {
return defaultVal;
}
}
이전 코드와 달리 try에서 자원을 할당하는 것을 확인할 수 있으며, try 코드 블록이 끝나면 자동으로 자원을 종료해주기에 close도 작성하지 않아서 더욱 깔끔하다. 또한 여러 개의 예외에 대해서는 try로 처리할 수 있다.