본문 바로가기

도서/이펙티브 자바

[이펙티브 자바] 9. try-finally 보다는 try-with-resources를 사용하라

회수를 보장해야하는 자원을 다룰 때는, try-with-resources를 사용하자.

 

 

자바에는 InputStream, OutputStream, java.sql.Connection 처럼 close로 직접 닫아야하는 자원이 많다.

자원을 닫고 보장하는 방식으로, 두 가지를 사용한다. 

1. try-finally 방식

 

자원이 여러개인 경우 아래 코드처럼 지저분해진다.

또한 try-finally 모두에서 예외가 발생할 수 있는데,

⭐️ try-finally의 문제점은 finally에서 예외가 발생하면 try 예외는 덮힌다는 점이다.

이는 디버깅을 어렵게 만든다. 

static void copy(String src, String dst) throws IOException {
	InputStream in = new FileInputStream(src);
    try {
    	OutputStream out = new FileOutputStream(dst);
        try {
        	byte[] buf = new byte[BUFFER_SIZE];
           	int n;
            while((n = in.read(buf)) >= 0)
            	out.write(buf, 0, n);
            } finally {
            	out.close();
           	} finally {
            	in.close();
            }
       	}
    }
}

 

2. try-with-resources 

자바 7부터 도입된 방식으로 읽기 쉽다.

static void copy(String src, String dst) throws IOException {
    try (InputStream in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dst)) {
        
        byte[] buf = new byte[BUFFER_SIZE];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
}

 

 

try 블럭이 수행되고 자동으로 close가 호출되어, 내부에서 close를 작성하지 않아도 된다.

out.close();
in.close();

 

또한 close 과정에서 예외가 발생하면 (위 try-finally의 finally 부분)

try 에서 발생한 예외 뒤에 suppressed(숨겨짐) 라는 꼬리표를 달고 추가된다.

⭐️ try-finally와 달리 첫 번째 예외를 덮지 않고 뒤에 추가된다.

 

suppressed 된 예외는 getSuppressed 메서드를 사용하면 가져올 수 있다.

 

try-finally에서 처러 catch 절을 사용할 수 있다. ➡️  try 중첩을 줄이면서 다수의 예외처리가 가능하다.

 

 

반응형