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)
{
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.
Innerhalb der runden Klammern nach try können auch mehrere Statements stehen (getrennt mit Semikolon). Bedingung ist dabei, daß damit immer Resourcen geöffnet werden, die AutoCloseable sind.
Voraussetzung für try-with-resources ist, das die in der Klammer geöffnete Resource automatisch geschlossen werden kann. Dazu wurde das Interface Autocloseable 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."
Das in 1.5 eingeführte Interface Closeable ist nun ein Unterinterface von AutoCloseable geworden. Eine Klasse, die Closeable implementiert implementiert damit automatisch auch das Interface AutoCloseable, da AutoCloseable dieselbe Methode vereinbart wie Closeable. Umgekehrt gibt es aber einige wenige Klassen (FileLock,XMLDecoder, XMLEncoder), die Autocloseable implementieren, aber nicht Closeable.
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) { 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()); } } } } }