Programming/JAVA

✅ Java Try-with-Resources, 제대로 알고 쓰자!

철부지개발자 2025. 3. 2. 12:43
반응형

자동으로 리소스를 닫아준다? 🤔

자바에서 파일, 소켓, 데이터베이스 연결 같은 리소스를 사용할 때,
우리는 항상 닫아주는 코드(close()) 를 작성해야 합니다.

 

근데… 실수로 안 닫으면? 💥 메모리 누수 발생!
예외가 발생하면? 💥 자원 누수 발생!

 

그래서 등장한 게 바로 Try-with-Resources 구문입니다!

💡 try 블록을 빠져나갈 때, 자동으로 close()를 호출해주는 기능입니다.

 

오늘은 try-with-resources가 뭔지, 왜 필요한지, 어떻게 쓰는지 예제 코드로 쉽게 설명해드릴게요! 🚀


📌 기존 try-catch에서 close() 직접 호출해야 하는 문제

자바 7 이전에는 리소스를 사용한 후,
항상 finally 블록에서 close()를 직접 호출해야 했어요.

import java.io.*;

public class OldTryCatchExample {
    public static void main(String[] args) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("test.txt"));
            String line = reader.readLine();
            System.out.println("파일 내용: " + line);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 직접 close() 호출해야 함
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

💥 문제점?
✔️ finally 블록에서 close()를 직접 호출해야 해서 코드가 복잡
✔️ close() 자체도 예외가 발생할 수 있어서 추가적인 try-catch 필요


📌 Try-with-Resources로 간단하게 해결!

자바 7부터 try-with-resources 를 사용하면,
try 블록을 벗어날 때 자동으로 close()를 호출해 줍니다. 🚀

import java.io.*;

public class TryWithResourcesExample {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
            String line = reader.readLine();
            System.out.println("파일 내용: " + line);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

🎯 자동으로 reader.close()가 호출됩니다!
✔️ finally 블록 필요 없음!
✔️ 코드가 훨씬 간결해짐!


📌 여러 개의 리소스를 동시에 관리하기

여러 개의 리소스를 사용할 때도,
try 괄호 안에 ;로 구분해서 나열하면 자동으로 close() 됩니다.

import java.io.*;

public class MultiResourceExample {
    public static void main(String[] args) {
        try (
            FileInputStream fis = new FileInputStream("input.txt");
            FileOutputStream fos = new FileOutputStream("output.txt")
        ) {
            int data;
            while ((data = fis.read()) != -1) {
                fos.write(data); // 파일 복사
            }
            System.out.println("파일 복사 완료!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

💡 실행 순서:
1️⃣ fis (FileInputStream) 먼저 생성됨
2️⃣ fos (FileOutputStream) 나중에 생성됨
2️⃣ try 블록 실행 (파일 읽고 쓰기)
3️⃣ try 블록을 벗어나면, 자동으로 fos.close() → fis.close() 순서로 닫힘!

 

🎯 close() 호출 순서는 나중에 연 리소스부터 먼저 닫는다!


📌 직접 만든 클래스에서도 try-with-resources 사용 가능!

💡 AutoCloseable 인터페이스를 구현하면,
사용자 정의 클래스도 try-with-resources에서 자동으로 close() 호출 가능합니다!

class MyResource implements AutoCloseable {
    public void doSomething() {
        System.out.println("리소스 사용 중...");
    }

    @Override
    public void close() {
        System.out.println("리소스가 자동으로 닫혔습니다!");
    }
}

public class CustomResourceExample {
    public static void main(String[] args) {
        try (MyResource resource = new MyResource()) {
            resource.doSomething();
        }
    }
}

💡 실행 결과:

리소스 사용 중...
리소스가 자동으로 닫혔습니다!

😎 AutoCloseable 인터페이스만 구현하면, 내 클래스도 자동으로 close() 된다!


📌 Try-with-Resources, 언제 써야 할까?

✅ 파일, 네트워크, 데이터베이스 같은 자원(Resource) 을 사용할 때
✅ close() 호출을 자동으로 처리하고 싶을 때
✅ 예외가 발생해도 안전하게 리소스를 닫아야 할 때

 

❌ 단순한 객체(String, List 등)는 try-with-resources 필요 없음!


📌 정리 🎯

🔥 Try-with-Resources 핵심 정리

 

✅ try 블록 안에서 리소스를 선언하면, 자동으로 close() 호출
✅ finally 블록 없이도 자원 누수 방지 가능
✅ AutoCloseable 인터페이스를 구현하면 직접 만든 클래스도 사용 가능
✅ 여러 개의 리소스도 ;로 구분해서 한 번에 관리 가능
✅ 파일, 네트워크, DB 연결 같은 리소스에 필수!

 

🎯 리소스를 다루는 코드? 무조건 Try-with-Resources 쓰자!


📌 Try-with-Resources, 바로 써보세요! 🚀

오늘 Try-with-Resources 개념부터 실전 예제까지 쭉 정리해봤는데요!
확실히 코드가 간결해지고, 예외 처리가 안전해졌죠? 😆

 

✅ "자원을 사용하고 닫아야 하는 코드가 있다?" → 무조건 Try-with-Resources!
✅ "close() 호출 깜빡해서 메모리 누수 생길까 걱정?" → 걱정 끝!

 

혹시 더 궁금한 점 있으면 댓글 남겨주세요! 🚀

반응형