Advanced Java Services | try with resources |
import java.io.FileReader; import java.io.IOException; import java.io.BufferedReader; /** Try without Resources */ public class Main { public static void main(String[] args) { BufferedReader br = null; try { String line; br = new BufferedReader(new FileReader("someFile.txt")); while((line = br.readLine()) != null) { System.out.println(line); } } catch(IOException ex) { ex.printStackTrace(); } finally { try { if (br != null) br.close(); } catch(IOException ex) { ex.printStackTrace(); } } } }
Die try-catch Klausel in finally ist notwendig, da close() eine IOException wirft. Zudem ist die Abfrage notwendig, ob br nicht etwa null ist. Dies umständliche Prozedur kann man mit der neuen Konstruktion vermeiden.
import java.io.FileReader; import java.io.IOException; import java.io.BufferedReader; /** Try with Resources */ public class Main { public static void main(String[] args) { BufferedReader br = null; try (BufferedReader br = new BufferedReader( new FileReader("someFile.txt"))) { String line; while((line = br.readLine()) != null) { System.out.println(line); } } catch(IOException ex) { ex.printStackTrace(); } } }
Nach try kann nun eine runde Klammer stehen, in der man die Resource öffnet. Wenn man try mit dieser Syntax verwendet wird die Resource automatisch geschlossen, ein finally ist also nicht mehr notwendig.
Voraussetzung für try-with-resources ist, das die in der Klammer geöffnete Resource automatisch geschlossen werden kann. Dazu wurde das Interface Autoclosable eingeführt, das als einzige Methode void close() throws Exception enthält. Alle Klassen der API, die eine passende close()-Methode enthalten, implementieren ab Java 7 diese Interface: "This method is invoked automatically on objects managed by the try-with-resources statement."
Die Methode close() kann, wie man an der Signatur sieht, durchaus Exceptions werfen. Sie werden aber im einfachen try-with-resources unterdrückt. Wer auf diese Exceptions achten will kann dies mit der neuen Methode getSupressed(), die in der Basisklasse Throwable aller Exceptions neu eingeführt wurde. Sie liefert ein Array vom Typ Throwable zurück, das alle unterdrückten Exceptions enthält. Die unterdrückten Exceptions werden werden im catch()-Zweig abgefragt.
import java.io.FileReader; import java.io.IOException; import java.io.BufferedReader; /** Try with Resources */ public class Main { public static void main(String[] args) { BufferedReader br = null; try (BufferedReader br = new BufferedReader( new FileReader("someFile.txt"))) { String line; while((line = br.readLine()) != null) { System.out.println(line); } } catch(IOException ex) { ex.printStackTrace(); if (ex.getSuppressed() != null) { for(Throwable t : ex.getSuppressed()) { System.out.println(t.getMessage()); } } } } }