기본적으로 close() 메서드를 사용하지 않아서 편합니다.
다음 예시는 이미 close() 메서드를 호출하고 있는 것입니다.
public class AutoCloseTest2 {
public static void main(String[] args) {
// try-with-resources 예시 만들기
Path path = Path.of("src/trycatch/example.txt");
// try-with-resources 예시 만들기
try (
BufferedWriter w = new BufferedWriter(new FileWriter(path.toFile()));
BufferedReader r = new BufferedReader(new FileReader(path.toFile()))) {
w.write("Hello, World! dsg!!!!!!!!");
w.flush();
// 파일 읽기
r.lines().forEach(System.out::println);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public class AutoCloseTest {
public static void main(String[] args) {
BufferedWriter w = null;
BufferedReader r = null;
Path path = Path.of("src/trycatch/example.txt");
try {
// Writing to the file
w = new BufferedWriter(new FileWriter(path.toFile()));
w.write("Hello, World! dsg!!!!!!!!!!!!!!!!!!!!!!!!!");
w.flush();
// Reading from the file
r = new BufferedReader(new FileReader(path.toFile()));
r.lines().forEach(System.out::println);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// Closing resources in the finally block
try {
if (w != null) {
w.close();
}
if (r != null) {
r.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
참고)
🤔BufferedReader
, BufferedWriter
객체들은 close()를 자동으로 호출해주는 AutoCloseable 인터페이스를 상속하는 객체라서 따로 안해줬다! 하지만, try-with-resource 구문을 사용하면 반드시, AutoCloseable 인터페이스를 사용해야 하는 걸 잊으면 안된다!
public class ResourceV2 implements AutoCloseable { // AutoCloseable 인터페이스를 구현 try-with-resources 사용 close() 자동 호출
private String name;
public ResourceV2(String name) {
this.name = name;
}
public void call() {
System.out.println(name + " call");
}
public void callEx() throws CallException {
System.out.println(name + " callEx");
throw new CallException(name + " ex");
}
@Override
public void close() throws CloseException {
System.out.println(name + " close");
throw new CloseException(name + " ex");
}
}
리소스 누수 방지:
모든 리소스가 제대로 닫히도록 보장한다. 실수로 finally 블록을 적지 않거나, finally 블럭 안에서 자원 해제 코드를 누락하는 문제들을 예방할 수 있다.
코드 간결성 및 가독성 향상:
명시적인 close() 호출이 필요 없어 코드가 더 간결하고 읽기 쉬워진다.
스코프 범위 한정:
예를 들어 리소스로 사용되는 resource1,2 변수의 스코프가 try 블럭 안으로 한정된다.
따라서 코드 유지보수가 더 쉬워진다.
조금 더 빠른 자원 해제:
기존에는 try catch finally로 catch 이후에 자원을 반납했다. Try with resources 구분은 try 블럭이 끝나면 즉시 close() 를 호출한다.
자원 정리 순서:
먼저 선언한 자원을 나중에 정리한다.
부가 예외 포함: 다음 내용에서 설명
try-with-resources 를 사용하는 중에 핵심 로직 예외와 자원을 정리하는 중에 발생하는 부가 예외가 모두 발생하면 어떻게 될까?
try-with-resources 는 핵심 예외를 반환한다.
부가 예외는 핵심 예외안에 Suppressed 로 담아서 반환한다.
개발자는 자원 정리 중에 발생한 부가 예외를 e.getSuppressed() 를 통해 활용할 수 있다.
try-with-resources 를 사용하면 핵심 예외를 반환하면서, 동시에 부가 예외도 필요하면 확인할 수 있다.
참고로 자바 예외에는 e.addSuppressed(ex) 라는 메서드가 있어서 예외 안에 참고할 예외를 담아둘 수 있다. 참고
로 이 기능도 try-with-resources 와 함께 등장했다.