Menu
Coddy logo textTech

Try With Resources 패턴

Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 87개 중 62번째.

파일 스트림이나 데이터베이스 연결과 같은 리소스를 사용할 때는 작업이 끝나면 항상 닫아야 합니다. 그렇지 않으면 메모리 누수가 발생할 위험이 있습니다. 전통적인 approach에서는 finally 블록을 사용하지만, 장황하고 오류가 발생하기 쉽습니다.

Java의 try-with-resources 문은 block이 완료되면 리소스를 자동으로 닫습니다. AutoCloseable 인터페이스를 implements하는 모든 class는 이 구문과 함께 사용할 수 있습니다:

// 전통적인 접근 방식 - 장황하고 위험함
BufferedReader reader = null;
try {
    reader = new BufferedReader(new FileReader("file.txt"));
    String line = reader.readLine();
} finally {
    if (reader != null) {
        reader.close();  // 예외를 던질 수도 있음!
    }
}

// Try-with-resources - 깔끔하고 안전함
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    String line = reader.readLine();
}  // 여기서 자동으로 닫힘

여러 리소스는 세미콜론으로 구분하여 관리할 수 있습니다. 리소스는 선언된 순서의 역순으로 닫힙니다:

try (FileReader fr = new FileReader("input.txt");
     BufferedReader br = new BufferedReader(fr)) {
    // 두 리소스를 모두 사용
}  // br이 먼저 닫히고, 그 다음 fr

자신만의 자동 닫기 가능 클래스를 만들려면 AutoCloseable 인터페이스와 해당 인터페이스의 단일 close() 메서드를 구현하세요:

public class DatabaseConnection implements AutoCloseable {
    public DatabaseConnection() {
        System.out.println("Connection opened");
    }
    
    @Override
    public void close() {
        System.out.println("Connection closed");
    }
}

이 패턴은 처리 중 예외가 발생하더라도 리소스가 항상 적절하게 해제되도록 보장합니다.

challenge icon

챌린지

쉬움

try-with-resources의 강력한 기능을 보여 주는 리소스 관리 시스템을 만들어 봅시다! 연결과 세션 관리를 시뮬레이션하는 사용자 정의 자동 close 가능 class를 만들고, 항상 적절하게 정리되도록 할 것입니다.

코드를 세 개의 파일로 구성합니다:

  • Connection.java: 데이터베이스 연결을 시뮬레이션하는 class를 Create하세요. Connection class는 AutoCloseable을 implements해야 합니다. 연결 이름(String)을 위한 private field, 이름을 받아 [name] connection opened를 출력하는 constructor, Executing on [name]: [sql]을 출력하는 query(String sql) method, 그리고 [name] connection closed를 출력하는 필수 close() method가 필요합니다.
  • Session.java: 사용자 세션을 시뮬레이션하는 또 다른 자동 close 가능 class를 Create하세요. Session class 역시 AutoCloseable을 implements해야 합니다. 사용자 이름(String)을 위한 private field, 사용자 이름을 받아 Session started for [username]을 출력하는 constructor, [username] performed: [action]을 출력하는 performAction(String action) method, 그리고 Session ended for [username]을 출력하는 close() method를 포함하세요.
  • Main.java: 리소스 관리 시스템을 하나로 결합합니다! 연결 이름, 사용자 이름, 수행할 action이라는 세 가지 input을 받습니다.

    먼저 단일 리소스 관리를 시연합니다. === Single Resource ===를 출력한 다음, try-with-resources를 사용하여 주어진 이름으로 Connection을 Create하세요. try block Inside에서 query("SELECT * FROM users")를 Call하세요. block이 ended되면 연결이 Automatically close되어야 합니다.

    다음으로 Multiple 리소스를 시연합니다. blank line을 출력한 다음 === Multiple Resources ===를 출력하세요. 동일한 이름을 사용하는 Connection과 사용자 이름을 사용하는 Session 모두에 try-with-resources를 사용하고, 세미콜론으로 구분하여 해당 순서로 선언하세요. try block Inside에서 먼저 연결에 대해 query("INSERT INTO logs")를 Call한 다음, 세션에서 input action을 사용하여 performAction을 Call하세요. 리소스가 reverse order로 close되는 방식을 확인하세요!

다음 순서로 세 가지 input을 받습니다: 연결 이름(String), 사용자 이름(String), action(String).

try-with-resources가 명시적인 close Call과 finally block의 필요성을 어떻게 없애는지 확인하세요. exception이 발생하더라도 리소스는 close되는 것이 보장되며, Multiple 리소스는 선언된 reverse order로 close됩니다!

직접 해보기

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String connectionName = scanner.nextLine();
        String username = scanner.nextLine();
        String action = scanner.nextLine();
        
        // === Single Resource ===
        // TODO: 헤더 출력하기
        // TODO: try-with-resources를 사용하여 Connection 생성하기
        // TODO: Inside the try block, call query("SELECT * FROM users")
        
        // === Multiple Resources ===
        // TODO: 빈 줄과 헤더 출력하기
        // TODO: Connection과 Session 모두에 try-with-resources 사용하기
        // TODO: try 블록 내부:
        //       - Call query("INSERT INTO logs") on the connection
        //       - session에서 입력받은 action으로 performAction 호출하기
        
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Java 컴파일러