-
[Java] try with resources란?Language/Java 2020. 2. 27. 22:40728x90반응형
자바를 이용해 외부 자원에 접근하는 경우 주의해야할 점은 외부자원을 사용한 뒤 반납을 해줘야 한다는 점이다.
1. 자원 반납과 finally
1-1) 자원반납 문제
1234변수1 = new 자원객체1(); // 자원 할당변수1.작업();변수1.close(); // 자원 반납위 코드에서 작업() 메소드가 에러없이 실행된 경우라면 close() 메소드가 정상적으로 작동해서 자원을 반납한다.
하지만 작업() 메소드에서 에러가 발생한다면 close( 메소드가 실행되지 않아서 자원이 반납하지 못하는 문제가 생긴다.
1-2) finally 블럭에서 자원 반납
12345678910111213변수1 = null;변수2 = null;try {변수1 = new 자원객체1();변수2 = new 자원객체2();변수1.작업();변수2.작업();...} finally {if (변수1 != null) 변수1.close();if (변수2 != null) 변수2.close();}위처럼 finally 안에 close() 메소드를 쓰게 되면 finally는 에러와 관계없이 항상 실행되기 때문에 자원 반납이 가능해진다.
2. try with resource 문법과 자원 반납
자바 1.7에 추가된 try with resource 문법을 사용하면 훨씬 간결하게 자원 반납 문제를 해결할 수 있다.
2-1) try wih resource 문법
1234try (변수1 = new 자원객체1()) {...}try with resource부터는 try 안에서 자원할당을 하면 자동으로 close() 메소드가 호출이 되기 때문에 finally 블록을 생략해도 된다.
12345try (변수1 = new 자원객체1();변수2 = new 자원객체2()) {...}자원할당이 여러개라면 위와 같이 구현한다.
12345678try (변수1 = new 자원객체1();변수2 = new 자원객체2()) {...try (변수3 = new 자원객체3()) {...}}try문장을 중첩하여 사용할 수도 있다.
실행흐름이 try 블럭을 빠져 나갈 때, 자원객체의 close 메소드가 자동으로 호출된다. exception이 발생해서 실행흐름이 점프할 때에서, 자원객체의 close 메소드는 반드시 자동으로 호출된다. (자세한건 아래에 다시 설명한다)
예제 코드와 함께 이해해보자
1234567891011121314151617181920import java.io.BufferedReader;import java.io.FileReader;public class Example1 {static void printFile(String 파일명) throws Exception {BufferedReader reader = new BufferedReader(new FileReader(파일명));String s;while ((s = reader.readLine()) != null) {System.out.println(s);}reader.close();}public static void main(String[] args) throws Exception {String 파일명 = "e:/temp/테스트.txt";printFile(파일명);}}만약 printFile 메소드를 실행하는 도중에 에러가 발생한다면 close() 메소드를 실행할 수 없기 때문에 자원 반납을 하지 못하는 문제가 발생한다.
123456789101112131415161718192021222324import java.io.BufferedReader;import java.io.FileReader;public class Example2 {static void printFile(String 파일명) throws Exception {BufferedReader reader = null;try {reader = new BufferedReader(new FileReader(파일명));String s;while ((s = reader.readLine()) != null) {System.out.println(s);}} finally {if (reader != null) reader.close();}}public static void main(String[] args) throws Exception {String 파일명 = "e:/temp/테스트.txt";printFile(파일명);}}이번 코드는 try ~ finally를 이용한 것이다. finally는 에러가 발생해도 반드시 실행되기 때문에 자원 반납이 가능하다.
그러면 어떻게 try wtih resource를 썼다고 자원 반납을 자동으로 하는것일까?
일단 먼저 생각할 것은 try() 안에 들어올 수 있는 것은 AutoCloseable 구현체뿐이다.
AutoCloseable 인터페이스 안에 close() 메소드가 존재한다. 따라서 AutoCloseable 인터페이스를 구현한 클래스는 close() 메소드를 구현해야 한다.
다음 예제 코드를 보자
1234567891011121314151617181920212223242526class MyResource implements AutoCloseable {public void MyResource() {System.out.println("자원이 할당됨");}public void 작업() throws Exception {System.out.println("작업 중 에러 발생");throw new Exception();}@Overridepublic void close() throws Exception {System.out.println("자원이 반납됨");}}public class Example4 {public static void main(String[] args) throws Exception {try (MyResource resource = new MyResource()) {resource.작업();}}}위의 코드를 실행하면 close() 메소드가 실행되어 "자원이 반납됨" 이 출력되는 것을 확인할 수 있다.
반응형'Language > Java' 카테고리의 다른 글
[Java] char배열과 String 클래스의 차이는? (0) 2020.03.31 [Java] Java는 Call by Value 일까? Call by Reference 일까? (0) 2020.03.17 [Java] Generic 개념 및 정리 (0) 2020.01.22 [Java] equals() 해시코드 비교 및 개념 정리 (0) 2020.01.19 [Java] Iterable 과 Iterator 이란? (1) 2020.01.18