Languages/Java

[Java] try-with-resources 예외 처리

효딩 2024. 8. 22. 17:15

 

강의 중에 try-catch-finally 구문 말고도 가독성이 좋은 try-with-resources 구문이 있다는 것을 배웠다.

그래서 프로젝트 중 사용해 보았는데,

팀원의 PR 코드 리뷰에 이런 질문을 했다.

 

따로 빼면 안되지 않나 ..? 라는 생각만 들 뿐 사실 확신이 없었다..

답변을 하기 위해 이것 저것 찾아 보고 답변은 했지만,

이 기회에 try-with-resources 구문을 제대로 정리하고 가는 게 좋을 것 같아서 정리하려 한다.

 

자주 참고하는 inpa님의 티스토리를 기반으로 작성하였다.

 

Java Resource의 예외 처리

보통 resource란 외부의 데이터(DB, Network, File)를 일컫는다.

이런 resource들은 자바 내부에 위치한 요소들이 아니기 때문에, 이러한 프로세스 외부에 있는 데이터를 자바 코드에서 접근하려 할 때 문제(예외)가 발생할 수 있는 여지가 있다.

 

특히나 이런 입출력 관련된 resource들에 접근해서 사용하고 나면 닫는 것이 굉장히 중요하다.

왜냐하면 어떤 resource를 사용하다가 다른 곳에서 같은 resource에 접근해 사용하다 보면 꼬일 수 있기 때문이다.

 

예를 들어 외부 텍스트 파일에 접근해서 내용을 쓰고 닫는 로직을 자바에서 구현한다고 하자.

import java.io.FileWriter;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        FileWriter file = null;
        try {
            file = new FileWriter("data.txt");
            file.write("Hello World");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            file.close(); 
            // 작업중에 예외가 발생하더라도 파일이 닫히도록 finally블럭에 넣음
			// 근데 close()가 예외를 발생시키면 문제가 됨
        }
    }
}

data.txt 파일을 읽는데 예상치 못한 오류가 발생할 가능성이 있으므로

IOException를 불러와 예외 처리 한다.

그리고 마지막에 외부 resource는 사용했으면 반드시 닫아 주어야 하므로

finally 문으로 파일을 close() 처리 한다.

 

하지만 파일을 닫는 동작 코드 자체도 IOException 예외가 일어날 수 있는 동작이기 때문에

이 부분도 예외 처리를 해주어야 한다.

 

import java.io.FileWriter;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        FileWriter file = null;
        try {
            file = new FileWriter("data.txt");
            file.write("Hello World");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
        	// close()에서 발생하는 예외를 처리하기 위해서 아래와같이 바꿀수도 있지만 코드가 복잡해져서 좋지않다.
            try {
                file.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

따라서 우리는 txt파일을 열고 닫는 코드를 쓰려고

예외 처리를 위해 이렇게 길게 작성해 주어야 하고,

이런 코드는 가독성이 좋지 않다.

 

그래서 자바 7버전부터 새로운 예외 처리 문법이 생겼는데 그게 바로

try-with-resource 구문이다.

 

Try with Resource 문

JDK1.7부터 try-with-resource 문이라는 문법이 새로 추가 되었다.

다음과 같다.

 

try 블록에 괄호()를 추가하여 파일을 열거나 자원을 할당하는 명령문을 명시하면,

해당 try 블록이 끝나자마자 자동으로 파일을 닫거나 할당된 자원을 해제해 준다.

try (파일을 열거나 자원을 할당하는 명령문) {
	...
}

 

 

따라서 위의 코드를 try-with-resources문으로 바꾸면 다음과 같이 된다.

import java.io.FileWriter;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try(FileWriter file = new FileWriter("data.txt")) {
            file.write("Hello World");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

괄호 안에 객체를 생성하는

FileWriter file = new FileWriter("data.txt") 라는 문장을 넣으면,

따로 close()하지 않아도 try 블럭을 벗어나는 순간 자동적으로 close()가 호출된다.

 

그리고 다음에 catch 또는 finally 블럭이 수행된다.

 

괄호 안에 IO 객체 문장을 두 개 이상 넣어줄 수도 있다.

이때는 세미콜론으로 각 문장을 구분해 주어야 한다.

 

// try 괄호 안에 두문장 이상 넣을 경우 ';'로 구분한다.
try(
	FileInputStream fis = new FileInputStream("a.txt");
    DataInputStream dis = new DataInputStream(fis)
) {
	
    while(true){
    	score - dis.readInt();
        System.out.println(score);
        sum += score;
    }
    
} catch (EOFException e){
    System.out.println("점수의 총합은 " + sum + "입니다.");
} catch (IOException ie){
    ie.printStackTrace();
}

 

AutoClosable 인터페이스

try-with-resources 문으로 사용될 수 있기 위해서는AutoCloseable 인터페이스를 구현 받아야 한다.

AutoCloseable 인터페이스를 구현한 클래스는 파일 입출력 스트림, 데이터베이스 연결 등 다양할 수 있다.

이러한 클래스의 인스턴스를 try-with-resources 구문 안에서 생성하면, 구문이 종료될 때 자동으로 자원이 해제된다.

 

 

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC-Try-With-Resource-%EB%AC%B8%EB%B2%95

 

☕ 자바 Try With Resource 예외 처리

자바 Resource의 예외 처리 보통 resource란 외부의 데이터(DB, Network, File)를 일컫는다. 이런 resource들은 자바 내부에 위치한 요소들이 아니기 때문에, 이러한 프로세스 외부에 있는 데이터에 자바 코

inpa.tistory.com

https://f-lab.kr/insight/understanding-autocloseable-and-try-with-resources-in-java?gad_source=1&gclid=EAIaIQobChMIhYGqnZKIiAMVT-0WBR0SnhuZEAAYASAAEgIS5vD_BwE

 

자바의 AutoCloseable 인터페이스와 try-with-resources 이해하기

자바의 AutoCloseable 인터페이스와 try-with-resources 구문을 통한 효율적인 자원 관리 방법에 대해 알아봅니다.

f-lab.kr