item9. try-finally 보다는 try-with-resource를 사용하라

이월(0216tw)·2024년 6월 1일
0

effective java

목록 보기
3/7

직접 close 해야하는 객체

이전 item 7 에서 다 쓴 객체 참조를 해제하라 라는 주제를 정리하면서 가비지컬렉터(이하 GC) 가 자바 내에서 더이상 참조되지 않는 객체 등을 해제(소멸) 시켜 준다고 했다.
(언제 GC가 실행될지는 내부 알고리즘에 따름)

하지만 즉시 자원을 해제할 필요가 있는 경우에는 개발자가 해당 객체를 사용한 후 직접 닫아줘야 한다. 예를 들어 FileWriter 등의 파일작업이나 Connection DB작업 등이 있다.

물론 사용자가 깜빡해도 나중에 GC가 처리하거나 finalizer 등을 사용할 수 있다.
하지만 GC는 참조가 해제되지 않은 경우에는 이를 소멸시킬 수 없다. 그리고 finalizer는 언제 실행될지 몰라 신뢰성이 부족하다 ( item8. finalizer와 cleaner 사용을 피하라 참고 )


try-finally와 try-with-resource 차이는?

(1) 직접 close()를 하냐 안하냐 차이

try-finally는 finally 부분에 해당 close() 를 직접 실행해주어야 하는 반면에, try-with-resource는 try 부분이 종료되는 순간 바로 close()가 자동 실행된다.
그래서 try-with-resource에 사용되는 객체는 AutoCloseable 인터페이스의 close()를 구현해야만 한다.

[ 출처 ] https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html

AutoCloseable 에는 close() 메서드 하나밖에 없고 이미 많은 클래스가 해당 인터페이스를 구현해놓았다

try-finally 소스코드

FileWriter file1 = null;
FileWriter file2 = null;
FileWriter file3 = null;

try { 
   file1 = new FileWriter("hello1.txt"); 
   file2 = new FileWriter("hello2.txt"); 
   file3 = new FileWriter("hello3.txt"); 
   
   file1.write("write1");
   file2.write("write2");
   file3.write("write3");

} catch( ... ) {

} finally { //직접 닫기 처리, 만약 하나라도 깜빡한다면 ??? 
   file1.close();
   file2.close();
   file3.close(); 
}

(2) 여러 객체가 있어도 모두 close() 됨을 보장한다.

위처럼 여러개의 파일 객체가 열려있고 만약 실수로 하나를 close() 하지 않는다면 잠재적인 위험이 될 수 있을 것이다. 이번에는 try-with-resource로 진행해보자.

try-with-resource 소스코드

try ( 
    FileWriter file1 = new FileWriter("hello1.txt"); 
    FileWriter file2 = new FileWriter("hello2.txt"); 
    FileWriter file3 = new FileWriter("hello3.txt"); 
) {   
    file1.write("write1");
    file2.write("write2");
    file3.write("write3");

} catch( ... ) {} 
//따로 finally 할 필요없이 try가 종료되는 순간 해당 자원이 모두 닫힘

(3) 소스코드의 가독성이 증가한다.

(4) finally 에서 예외가 발생할 수 있는데 이를 예방한다.

첫번째코드에서 만약 finally 에서 예외가 발생한다면 결국 예외처리를 하거나 프로그램이 종료될 것이다. 하지만 두번째 코드인 try-with-resource는 finally를 사용하지 않으니 이 문제점이 해결되는 것이다.

👨‍💻정리
try-finally 보다 try-with-resource 사용을 권고한다. 단 아래 조건을 충족해야 한다

(1) java7부터 사용가능함
(2) (★) 해당 객체가 AutoCloseable의 close 메서드를 구현해야함
(3) 복잡한 리소스 관련 로직인 경우에는 try-finally가 나을 수도 있음

profile
Backend Developer (Financial)

0개의 댓글