[java]try-with-resource
1
java7 부터 아래와 같이 try-catch-finally 문을 이용해 자원해제를 하던 것이 try-with-resource 를 이용해 더 간결하게 코드작성이 가능해 졌다.
- try catch finally 방식 예제
try { scanner = new Scanner(new File("test.txt")); while (scanner.hasNext()) { System.out.println(scanner.nextLine()); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (scanner != null) { scanner.close(); } }
- try with resource 방식 예제
try (Scanner scanner = new Scanner(new File("test.txt"))) { while (scanner.hasNext()) { System.out.println(scanner.nextLine()); } } catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); }
- 자원 해제가 필요한 객체를 try 안에 선언하면 close 메소드를 자동으로 호출하게 된다 단 close가 호출되는 것은 AutoCloseable을 구현한 객체에만 해당된다.
2
AutoCloseable 를 구현하는 클래스 만들어 보자
public static void main(String args[]) {
try (CustomResource cr = new CustomResource()) {
cr.doSomething();
} catch (Exception e) {
}
}
private static class CustomResource implements AutoCloseable {
public void doSomething() {
System.out.println("Do something...");
}
@Override
public void close() throws Exception {
System.out.println("CustomResource.close() is called");
}
}
- 실행하면 아래처럼
Do something... CustomResource.close() is called
3
조금더 심화해서
- 여러 리소스는 세미콜론응로 구분해서 사용할수도 있음.
try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { while (scanner.hasNext()) { writer.print(scanner.nextLine()); } }
- 리소스 해제는 처음 획득한 리소스가 제일 마지막에 해제된다
public class AutoCloseableResourcesFirst implements AutoCloseable { public AutoCloseableResourcesFirst() { System.out.println("Constructor -> AutoCloseableResources_First"); } public void doSomething() { System.out.println("Something -> AutoCloseableResources_First"); } @Override public void close() throws Exception { System.out.println("Closed AutoCloseableResources_First"); } } . . public class AutoCloseableResourcesSecond implements AutoCloseable { public AutoCloseableResourcesSecond() { System.out.println("Constructor -> AutoCloseableResources_Second"); } public void doSomething() { System.out.println("Something -> AutoCloseableResources_Second"); } @Override public void close() throws Exception { System.out.println("Closed AutoCloseableResources_Second"); } } . . . private void orderOfClosingResources() throws Exception { try (AutoCloseableResourcesFirst af = new AutoCloseableResourcesFirst(); AutoCloseableResourcesSecond as = new AutoCloseableResourcesSecond()) { af.doSomething(); as.doSomething(); } }
순서는 아래처럼 된다.
Constructor -> AutoCloseableResources_First
Constructor -> AutoCloseableResources_Second
Something -> AutoCloseableResources_First
Something -> AutoCloseableResources_Second
Closed AutoCloseableResources_Second
Closed AutoCloseableResources_First
- 마지막으로 java9 이후부터는 아래처럼도 가능하다.
- final 로 선언을 하거나 첫번째 할당 후에 변경되지 않은(사실상 final 변수)? 경우 자동으로 해제 가능하다.
final Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))
try (scanner;writer) {
// omitted
}
- 참고
- https://www.baeldung.com/java-try-with-resources
- 등등