try-with-resources는 자원을 자동으로 관리하기 위한 구문으로, 자원을 명시적으로 닫지 않아도 자동으로 해제됩니다. 파일, 네트워크 소켓, 데이터베이스 연결과 같은 자원들은 반드시 사용 후 닫혀야 합니다. 자바 7에서 도입된 try-with-resources는 이러한 자원을 자동으로 해제하는 구조를 제공합니다.
자바에서 자원이란 사용 후 반드시 해제해야 하는 외부 시스템과의 연결을 의미합니다. 파일, 데이터베이스 연결, 네트워크 소켓 등이 자원에 해당합니다. 자원을 닫지 않으면 메모리 누수나 시스템 리소스 고갈 문제가 발생할 수 있습니다.
FileReader, BufferedReader 등Connection, Statement 등의 데이터베이스 관련 자원Socket 객체자원은 사용 후에 반드시 닫아야 하며, 닫지 않으면 리소스 누수로 이어져 시스템 성능에 영향을 미칠 수 있습니다.
try-with-resources 구문에 사용되는 자원은 반드시 AutoCloseable 또는 Closeable 인터페이스를 구현해야 합니다.try 블록이 끝나면 자동으로 close() 메서드가 호출되어 자원을 해제합니다.try 구문이 끝날 때 자동으로 닫히기 때문에 수동으로 자원을 해제하는 과정에서 발생할 수 있는 오류를 방지할 수 있습니다.자바 7 이전에는 자원을 해제하려면 try-catch-finally 구문에서 자원을 수동으로 닫아야 했습니다. 자원을 해제하지 않으면 메모리 누수나 시스템 오류가 발생할 수 있기 때문에, finally 블록에서 반드시 close() 메서드를 호출해야 했습니다.
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("test.txt"));
// 파일을 읽는 로직
String line = br.readLine();
System.out.println(line);
} catch (IOException e) {
// 예외 처리
e.printStackTrace();
} finally {
// 자원을 명시적으로 해제
if (br != null) {
try {
br.close(); // 자원을 반드시 닫아야 함
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
finally 블록에서 자원을 닫지 않으면 리소스 누수가 발생할 수 있습니다.null 확인 및 close() 호출을 반복해야 합니다.자바 7부터 도입된 try-with-resources는 자원을 자동으로 닫아주는 구조입니다. try 구문 안에서 자원을 생성하면, try 블록이 끝나면 자동으로 자원을 닫습니다. 이 덕분에 finally 블록에서 자원을 닫는 작업을 수동으로 할 필요가 없습니다.
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
// 파일을 읽는 로직
String line = br.readLine();
System.out.println(line);
} catch (IOException e) {
// 예외 처리
e.printStackTrace();
}
try 블록이 끝나면 자원이 자동으로 닫힙니다.finally 블록에서 수동으로 자원을 닫을 필요가 없어 코드가 간결해집니다.try-with-resources에서 사용할 수 있는 자원은 반드시 AutoCloseable 또는 Closeable 인터페이스를 구현해야 합니다. 두 인터페이스 모두 자원을 닫을 수 있는 메서드를 제공하지만, AutoCloseable은 자바 7에서 추가되었고, Closeable은 자바 5부터 존재합니다.
AutoCloseable은 자바 7에서 도입된 인터페이스로, 자원을 닫기 위한 close() 메서드를 정의합니다.AutoCloseable을 구현한 객체는 try-with-resources 구문에서 사용할 수 있습니다.public interface AutoCloseable {
void close() throws Exception;
}
Closeable은 자바 5에서 도입된 인터페이스로, I/O 자원을 닫기 위한 close() 메서드를 정의합니다.AutoCloseable이 새롭게 등장한 후, 기존의 Closeable 인터페이스에 AutoCloseable을 상속받는 구조가 추가되었습니다.변경된 이유는 try-with-resources 구문을 사용하면서 기존에 있던 Closeable을 포함하여 모든 자원을 자동으로 닫을 수 있도록 하기 위해서입니다.public interface Closeable extends AutoCloseable {
void close() throws IOException;
}
AutoCloseable은 모든 자원에 적용 가능한 범용적인 인터페이스로 Exception을 던질 수 있습니다.Closeable은 I/O 작업에 특화된 인터페이스로, IOException만 던질 수 있습니다. 주로 파일 입출력에 사용됩니다.try-with-resources를 사용하면 자원을 안전하게 해제할 수 있습니다. 자원 해제 코드를 수동으로 작성할 때 발생할 수 있는 실수를 줄일 수 있으며, 예외가 발생하더라도 자원이 자동으로 해제됩니다.
자원 해제 시 발생한 예외와 원래의 예외를 모두 처리할 수 있습니다. 기존 finally 블록에서는 자원을 닫는 과정에서 새로운 예외가 발생하면 원래 예외가 가려지는 문제가 있었습니다.
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line = br.readLine(); // 예외 발생 가능
System.out.println(line);
} catch (IOException e) {
// 예외 처리
e.printStackTrace();
} // 자원이 자동으로 해제됨
try-with-resources를 사용하면 자원을 닫는 finally 블록을 작성할 필요가 없으므로 코드가 간결해지고 가독성이 높아집니다. 여러 자원을 사용할 때도 하나의 try 구문에서 관리할 수 있습니다.
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"));
FileWriter fw = new FileWriter("output.txt")) {
String line = br.readLine();
fw.write(line);
} catch (IOException e) {
e.printStackTrace();
}
// 두 자원 모두 자동으로 해제됨
try-catch-finally를 사용할 경우 (자원 해제 중 예외가 발생할 때)import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryCatchFinallyExample {
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("test.txt"));
String line = br.readLine(); // 예외 발생 가능
System.out.println(line);
} catch (IOException e) {
// 파일 읽기 중 발생한 예외 처리
System.out.println("파일을 읽는 도중 오류 발생");
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close(); // 자원을 닫는 과정에서 예외 발생 가능
} catch (IOException e) {
// 자원 해제 중 발생한 예외 처리
System.out.println("자원을 닫는 도중 오류 발생");
e.printStackTrace();
}
}
}
}
}
catch 블록에서 해당 예외를 처리합니다.finally 블록에서 br.close()를 호출하여 자원을 닫으려고 하지만, 닫는 도중에 예외가 발생할 수 있습니다. 이렇게 되면 자원을 닫는 중 발생한 예외는 별도로 처리됩니다.try-with-resources를 사용할 경우 (자원 해제 중 예외가 발생할 때)import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line = br.readLine(); // 예외 발생 가능
System.out.println(line);
} catch (IOException e) {
// 파일 읽기 중 발생한 예외와 자원 해제 중 발생한 예외를 함께 처리
System.out.println("파일 읽기 또는 자원 해제 중 오류 발생");
e.printStackTrace();
}
}
}
try-with-resources에서는 자원이 자동으로 해제되므로, finally 블록을 수동으로 작성할 필요가 없습니다.try-with-resources에서 첫 번째 예외를 그대로 남겨두고, 자원 해제 중 발생한 예외는 suppressed exception으로 관리합니다.getSuppressed() 사용)try-with-resources는 자원을 닫는 중 발생한 예외를 억제된 예외(suppressed exception)로 저장합니다. 이를 확인하는 예시입니다.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesSuppressedExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("non_existent_file.txt"))) {
String line = br.readLine(); // 예외 발생 가능
} catch (IOException e) {
System.out.println("메인 예외: " + e.getMessage());
// 억제된 예외 확인
for (Throwable suppressed : e.getSuppressed()) {
System.out.println("억제된 예외: " + suppressed.getMessage());
}
}
}
}
getSuppressed() 메서드를 사용하면 자원을 닫는 중 발생한 억제된 예외들을 확인할 수 있습니다.try-with-resources를 사용하면 자원 해제 중 발생한 예외가 메인 예외에 억제된 형태로 추가되어, 두 예외를 모두 처리할 수 있습니다.try-with-resources는 자바 7에서 도입된 자원 관리 기능으로, 자원을 자동으로 닫아줍니다. 이로 인해, 자바에서 메모리 누수나 리소스 낭비 문제를 방지할 수 있습니다.try-catch-finally 구문에서 자원을 수동으로 닫는 문제를 해결합니다.AutoCloseable 또는 Closeable 인터페이스를 구현한 객체만 사용할 수 있지만, 이를 통해 코드가 간결해지고 예외 처리의 안전성이 보장됩니다.