try-with-resources는 자원을 자동으로 닫아주는 기능을 제공하는 Java 7부터 도입된 문법입니다.
finally 블록에서 명시적으로 close()를 호출할 필요 없음 AutoCloseable 또는 Closeable 인터페이스를 구현한 객체만 사용 가능 try-finally 방식Java 7 이전에는 finally 블록에서 close()를 명시적으로 호출해야 했습니다.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryFinallyExample {
public static void main(String[] args) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("test.txt"));
System.out.println(reader.readLine());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close(); // 명시적으로 close() 호출
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
finally 블록에서 close()를 호출해야 함 close() 호출 시 IOException이 발생할 가능성이 있어 또다시 try-catch가 필요 Java 7부터는 try 문에서 AutoCloseable을 구현한 리소스를 선언하면 자동으로 close()가 호출됩니다.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
System.out.println(reader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
finally 블록이 필요 없음 try-with-resources에서 선언할 수 있음 close()됨 (선언된 역순으로 해제됨) import java.io.*;
public class MultiResourceExample {
public static void main(String[] args) {
try (
FileReader fr = new FileReader("test.txt");
BufferedReader br = new BufferedReader(fr)
) {
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
br이 먼저 닫히고, 이후 fr이 닫힘 (LIFO 순서) AutoCloseable 인터페이스 구현try-with-resources를 사용하려면 해당 클래스가 AutoCloseable 또는 Closeable 인터페이스를 구현해야 합니다.
class MyResource implements AutoCloseable {
@Override
public void close() {
System.out.println("MyResource is closed.");
}
public void doSomething() {
System.out.println("Doing something...");
}
}
public class CustomResourceExample {
public static void main(String[] args) {
try (MyResource resource = new MyResource()) {
resource.doSomething();
}
}
}
// 출력:
// Doing something...
// MyResource is closed.
AutoCloseable을 구현하면 try 블록 종료 시 자동으로 close()가 호출됨 try-with-resources에서 예외가 발생하면
1. try 블록에서 예외 발생
2. close() 호출 중 예외 발생 (Suppress 예외)
3. try 블록에서 발생한 예외가 우선 처리됨
class TestResource implements AutoCloseable {
@Override
public void close() throws Exception {
throw new Exception("Close 예외 발생!");
}
}
public class SuppressedExceptionExample {
public static void main(String[] args) {
try (TestResource tr = new TestResource()) {
throw new Exception("Main 예외 발생!");
} catch (Exception e) {
System.out.println("예외: " + e.getMessage());
for (Throwable suppressed : e.getSuppressed()) {
System.out.println("Suppressed 예외: " + suppressed.getMessage());
}
}
}
}
// 출력:
// 예외: Main 예외 발생!
// Suppressed 예외: Close 예외 발생!
close() 중 발생한 예외는 Suppressed Exception으로 저장됨 try-with-resources를 사용할 수 없는 경우AutoCloseable을 구현하지 않은 클래스는 사용 불가능 AutoCloseable을 구현하지 않은 경우, finally 블록에서 close()를 직접 호출해야 함 try-with-resources는 파일, DB 커넥션, 네트워크 소켓 등 리소스를 다룰 때 매우 유용합니다.
코드가 간결해지고 예외가 발생해도 안전하게 자원이 해제된다는 점이 큰 장점입니다.
실무에서도 JDBC, HTTP 연결, 파일 입출력 처리 시 적극 활용하면 좋다는 점을 다시 한번 느꼈습니다.