프로그래밍/JAVA

[JAVA] 자동 자원 반환 try-with-resources

리신 2022. 11. 22. 21:08
반응형

JDK1.7부터 try-catch-resources문이라는 try-catch문의 변형이 새로 추가되었다.

이 구문은 입출력(I/O)과 관련된 클래스를 사용할 때 유용하다.

 

주로 입출력에 사용되는 클래스 중에서는 사용한 후에 꼭 닫아 줘야 하는 것들이 있다.

그래서 사용했던 자원(resources)이 반환되기 때문이다.

 

🙄하지만 그렇게 사용하지 않고 finally를 사용하여 닫아주면 안 되는 건가?

try{
    fis = new FileInputStream("score.dat");
    dis = new DataInputStream(fis);
}catch(IOException ie){
	ie.printStackTrace();
} finally {
	dis.close();
}

위 코드처럼 할 경우 별 문제가 없어 보인다 하지만! close()가 예외를 발생시킬 수 있다는데 있다.

그래서 위 코드는 아래의 코드 처럼 해야 올바른 것이 된다.

 

try{
    fis = new FileInputStream("score.dat");
    dis = new DataInputStream(fis);
}catch(IOException ie){
	ie.printStackTrace();
} finally {
    try{
        if(dis != null)
           dis.close();
    }catch(IOException ie){
    	ie.printStackTrace();
    }
}

finally블럭 안에 try-catch문을 추가해서 close()에서 발생할 수 있는 예외를 처리하도록 변경했는데,

코드가 복잡해져서 별로 보기에 좋지 않고,

try블록과 finally블록에서 모두 예외가 발생하면, try블록의 예외는 무시된다.

 

이러한 문제점을 개선하기 위해서 try-with-resources문이 추가된 것이다.

 

그러면 어떻게 사용하는지 예제로 알아보자!

💎예제💎

try-with-resources 는 아래의 코드 같이 try에 자원을 전달하면, try 코드 블록이 끝나면 자동으로 자원을 종료해준다.

즉, 따로 finally 블록이나 catch 블록에 닫기 처리를 하지 않아도 된다.

try (SomeResource resource = getResource()) {
    use(resource);
} catch(...) {
    ...
}

하지만 이 때, try에 전달할 수 있는 자원은 AutoCloseable 인터페이스의 구현체로 한정된다.

* AutoCloseable 는 인터페이스고 자바 7부터 지원합니다.

public interface AutoCloseable {
    void close() throws Exception;
}

그리고 아래와 같이 try 안에는 복수의 자원 객체를 전달할 수도 있다.

try(FileInputStream fis = new FileInputStream("score.dat");
    DataInputStream dis = new DataInputStream(fis)) {
} catch(...) {
    ...
}

* 두 개의 객체를 전달할 경우는 ' ; ' 세미콜론으로 구분한다.

 

🙄두 예외가 동시에 발생하는 경우가 있다면 어떻게 되는 걸까?

→ 실제 발생한 예외를 알리고 나머지 하나의 예외는 억제된 예외로 다룬다.

억제된 예외에 대한 정보는 실제 발생한 예외에 저장된다.

 

Throwable에는 억제된 예외와 관련된 아래와 같은 메서드가 정의되어 있다.

void addSuppressed(Throwable exception)  억제된 예외를 추가
Throwable [] getSuppressed()     억제된 예외 (배열)를 반환

 

*참고서적

Java의 정석

 

반응형