앞선 item에서도 말했듯이, 프로그래머가 놓치기 쉬운 작업들로 인해 예측할 수 없는 성능문제로 이어질 수 있다. 결국 이번 item에서도 말하는 것은 프로그래머가 직접 관리하는 것보다 Java가 제공해주는 기능을 적극적으로 사용하자
인 것 같다.
item9 에서 try-finally
에 대한 설명과 간단한 예제를 통해 문제점을 설명하고 있다. 그리고 이를 보완하는 방법으로 try-with-resources
방법을 알려주고 있다.
static void firstLineOfFile(String path) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return;
br.readLine();
}finally {
br.close();
}
}
일반적으로 위와 같은 방법으로 close를 보장해주었다.
만약, 기기에 물리적 문제가 생긴다면 readLine() 메서드가 예외를 던지고 그리고 close() 메서드도 실패하게 된다. 이때 두번 째 예외가 첫번째 예외를 덮어씌우게돼 스택 추적 내역에 첫번 째 예외에 대한 정보가 남지 않는다.
이러한 문제점을 해결하기 위해 Java 7에서 try-with-resources
구조를 제공한다.
이 구조를 사용하려면 자원이 AutoCloseable을 구현
하고 있어야한다. 예제 코드를 통해 확인해보자.
먼저 AutoCloseable을 구현하고 있지 않은 자원을 try-with-resources 구조로 생성하려고 할 때이다.
public class NotAutoClose {
public void task(){
System.out.println("NotAutoClose task~");
}
}
이와 같이 단순한 클래스가 있다고 했을 때, try-with-resources 구조는 다음과 같은 것이다.
try (NotAutoClose not = new NotAutoClose()) {
not.task();
}
위 코드를 작성해보면 알겠지만 빨간 줄이 그어지는 것을 볼 수 있고, 실행시키면 다음의 메시지를 보게 될 것이다. 메시지만 봐도 AutoCloseable을 구현해야 한다는 것을 알 수 있을것이다.
그럼 이번엔 AutoCloseable을 구현한 자원을 생성해보자.
public class AutoClose implements AutoCloseable {
public void task(){
System.out.println("some task~");
}
@Override
public void close() throws Exception {
System.out.println("auto close");
}
}
static void runTry_With_Resources() throws Exception {
try (AutoClose auto = new AutoClose()) {
auto.task();
}
}
위 코드를 실행하면 some task
가 출력된 뒤 auto close
가 출력됨을 볼 수 있다. try-with-resources구조를 사용하여 자원을 생성하면, finally로 resource.close() 메소드를 생략할 수 있게되는 것이다.
공식문서를 보면 The close() method of an AutoCloseable object is called automatically when exiting a try-with-resources block for which the object has been declared in the resource specification header.
알 수 있듯이, AutoCloseable 객체의 close()메서드가 자동으로 호출됨을 확인 할 수 있다.
try-with-resource
에 대한 좀 더 자세한 내용은 이 공식문서를 보면 좋을 것 같다.
effective-java스터디에서 공유하고 있는 전체 item에 대한 정리글