try-with-resouces의 resources는 외부 데이터 자원을 말한다. (DB, Network, File, ...)
이 외부 데이터에 접근 하려고 할 때, 외부 데이터를 처리하려고 할 때 예외가 발생할 수 있다.
그렇다면, 왜 try-catch-finally가 있는데 try-with-resources를 만들었을까?
이유는 아래의 코드 예시를 보면 알 수 있다.
이 코드는 dummy.txt 파일을 읽으려 하고 있다.
하지만 실제로 해당 파일은 존재하지 않으며 예외 처리를 하게 될 것이다.
import java.io.FileReader;
import java.io.IOException;
public class FileParsing {
public static void main(String[] args) throws IOException {
FileReader file = null;
try {
file = new FileReader("./dummy.txt");
} catch (IOException e) {
throw new IOException();
} finally {
file.close();
// 해당 파일이 없어 예외 처리 후 finally문을 실행하려 함
// file이 존재하지 않으므로 NullpointerException 발생
}
}
}
이 상황에서는 file이 null인지 확인하는 조건문을 넣어주면 해결할 수 있다.
하지만 그 밖에 다른 상황들이 finally에서 예외를 발생시킬 수 있다.
그래서 자동으로 자원을 닫아주기 위해 try-with-resources가 생겨난 것이다.
(정확하게 예시를 못들겠네..)
파일을 닫지 않아고 당장은 큰 문제가 없긴 하다.
하지만 만약 소스 내 다른 곳에서 같은 파일에 접근하려고 한다면?
해당 파일은 열려있기 때문에 Lock이 걸려있다.
그러므로 다른 곳에서 사용하려고 해도 사용하지 못한다.
이러한 이유로 반드시 close를 해주어야 한다.
try-with-resource는 try에 자원 객체를 전달하면 try의 코드블록이 끝났을 때 자동으로 자원을 종료해준다.
이때 try에 전달할 수 있는 자원은 AutoCloseable
인터페이스 구현체만 가능하다.
import java.io.FileReader;
import java.io.IOException;
public class FileParsing {
public static void main(String[] args) throws IOException {
// 복수의 자원 작성 가능
// try가 끝나면 자원 자동 종료
try (FileReader fileReader = new FileReader("./dummy.txt");
FileReader fileReader2 = new FileReader("./dummy2.txt")) {
// 파일 처리 내용
}
}
}
try-with-resources는 예외 처리를 위한 것이라기 보다 예외가 발생하더라도 자원을 안전하게 종료하도록 하는 기능이라고 말하는 것이 맞다.
즉 try-with-resources는 자원 자동 종료만 수행하는 것이다.
그러므로 파일을 읽으려고 할 때 같은 처리를 하기 위해서는 따로 예외 처리를 해야만 한다.