English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
이 튜토리얼에서는 try-with-resources 표현식은 자원을 자동으로 닫습니다.
try-with-resources 표현식은 문장의 마지막에 모든 자원을 자동으로 닫습니다. 자원은 프로그램이 끝날 때 닫아야 할 객체입니다.
그 문법은 다음과 같습니다:
try(resource 선언) { // 자원의 사용 } catch(ExceptionType e1) { // catch 절 }
위의 문법에서 볼 수 있듯이, try를 다음과 같은 방식으로 선언합니다:-with-resources 표현식:
try 절에서 자원을 선언하고 인스턴스화합니다.
자원을 닫을 때 발생할 수 있는 모든 예외를 지정하고 처리합니다.
주의:try-with-resources 표현식은 AutoCloseable 인터페이스를 구현한 모든 자원을 닫습니다.
try 표현식을 구현하자-with-resources 표현식의 예제로 사용
import java.io.*; class Main { public static void main(String[] args) { String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { while ((line = br.readLine()) != null) { System.out.println("Line =>")+line); } } catch (IOException e) { System.out.println("try 블록 내에서 IOException이 발생하면=>" + e.getMessage()); } } }
test.txt 파일이 찾지 못되면 출력합니다.
try에서 IOException-with-resources block => test.txt (No such file or directory)
test.txt 파일이 찾겨지면 출력합니다.
try에 진입-with-resources block Line => test line
이 예제에서 사용하는 인스턴스 BufferedReader는 test.txt 파일에서 데이터를 읽습니다.
try-with-resources 표현式中 선언하고 인스턴스화된 BufferedReader는 try 문이 정상적으로 완료되든 예외가 발생하든其实例을 닫을 수 있습니다.
如果发生异常,则可以使用异常处理块或throws 키워드对其进行处理。
在上面的示例中,在以下情况下可以从try-with-resources语句引发异常:
找不到test.txt文件。
关闭BufferedReader对象。
也可以从try 블록中引发异常,因为文件读取可能随时因多种原因而失败。
如果从try 블록和try-with-resources语句都抛出异常,则会抛出try 블록中的异常,并抑制try-with-resources语句中的异常。
Java에서 7和更高版本中,可以通过Throwable.getSuppressed()从try 블록引发的异常中调用方法来检索抑制的异常。
此方法返回所有抑制的异常的数组。我们在catch 블록中得到了抑制的异常。
catch(IOException e) { System.out.println("Thrown exception=>" + e.getMessage()); Throwable[] suppressedExceptions = e.getSuppressed(); for (int i = 0; i < suppressedExceptions.length; i++) { System.out.println("Suppressed exception=>" + suppressedExceptions[i]); } }
这是使用try-with-resources的优点:
Java에서 7引入此功能之前,我们必须使用该finally 블록来确保关闭资源以避免资源泄漏。
这是一个类似于예제1的程序。但是,在此程序中,我们使用了finally 블록来关闭资源。
import java.io.*; class Main { public static void main(String[] args) { BufferedReader br = null; String line; try { System.out.println("进入try 블록"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) { System.out.println("Line =>")+line); } } catch (IOException e) { System.out.println("try 블록 내에서 IOException이 발생하면=>" + e.getMessage()); } finally { System.out.println("finally 블록에 진입"); try { if (br != null) { br.close(); } } catch (IOException e) { System.out.println("finally 블록 내에서 IOException이 발생하면=>"+e.getMessage()); } } } }
출력 결과
try 블록에 진입 Line =>test.txt 파일에서 line finally 블록에 진입
위의 예제에서 볼 수 있듯이, finally 블록을 사용하여 자원을 정리하면 코드가 더 복잡해집니다.
finally 블록 내의 BufferedReader 인스턴스를 닫을 때 IOException이 발생할 수 있음을 주목하셨나요? 따라서 이를 잡고 처리합니다.
try-with-resources 문장이 실행됩니다자동 자원 관리자원을 명시적으로 닫지 않아도 됩니다. JVM이 자동으로 닫아줍니다. 이는 코드의 읽음성과 작성이 더 쉬워집니다.
우리는 try를-with-resources를 분号으로 구분하여 여러 자원을 나열하여 문장에서 여러 자원을 선언할 수 있습니다;
import java.io.*; import java.util.*; class Main { public static void main(String[] args) throws IOException{ try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { while (scanner.hasNext()) { writer.print(scanner.nextLine()); } } } }
프로그램을 실행할 때 예외가 생성되지 않으면, Scanner object가 testRead.txt 파일에서 한 행을 읽고 새로운 testWrite.txt 파일에 쓰입니다.
여러 선언을 할 때, try-with-resources 문장은 이러한 자원을 반대 순서로 닫습니다. 이 예제에서는 먼저 PrintWriter 객체를 닫고, 그 다음 Scanner 객체를 닫습니다.
Java에서 7에서, 이 try-with-resources 문장은 한 제한이 있습니다. 자원은 그 블록 내에서 지역적으로宣言되어야 합니다.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) { // code }
Java에서 우리가 7자원을 블록 외부에서宣言하면 오류 메시지가 발생합니다.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) { // code }
이 오류를 해결하기 위해 Java 9 이 try를 개선했습니다-with-resources 문장을 사용하여 지역적으로 자원 참조가宣言되지 않았더라도 사용할 수 있습니다. 현재 코드는 컴파일 에러를 발생시키지 않습니다.