La Java 7 essayez-avec-les ressources de la syntaxe (également connu sous le BRAS (blocAutomatique de Gestion de la Ressource)) c'est sympa, court et simple lors de l'utilisation d'un seul AutoCloseable
des ressources. Cependant, je ne suis pas sûr de ce qui est la bonne idiome quand j'ai besoin de déclarer plusieurs ressources qui dépendent les uns des autres, par exemple un FileWriter
et BufferedWriter
qui l'enveloppe. Bien sûr, cette question concerne tout cas, si certains AutoCloseable
des ressources sont enveloppés, non seulement ces deux classes spécifiques.
Je suis venu avec les trois options suivantes:
1)
Le naïf idiome j'ai vu, c'est de déclarer que le haut-niveau wrapper dans le BRAS-géré variable:
static void printToFile1(String text, File file) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
C'est belle et courte, mais il est cassé. Parce que le sous-jacent FileWriter
n'est pas déclaré dans une variable, il ne sera jamais fermée directement dans le générés finally
bloc. Il sera fermé uniquement par le biais de l' close
méthode de l'emballage BufferedWriter
. Le problème, c'est que si une exception est levée à partir de la bw
s'constructeur, close
ne sera pas appelé et donc le sous-jacent FileWriter
ne sera pas fermé.
2)
static void printToFile2(String text, File file) {
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
Ici, les deux sous-jacent et de l'emballage des ressources sont déclarées dans le BRAS géré variables, de sorte que les deux d'entre eux seront certainement fermé, donc certainement que le sous-jacent fw.close()
sera appelée deux fois, directement pour la première et pour la seconde fois par l'habillage bw.close()
.
Cela ne devrait pas être un problème pour ces deux classes qui implémentent Closeable
(qui est un sous-type d' AutoCloseable
), dont le contrat stipule que plusieurs appels à l' close
sont autorisés:
Ferme ce flux et libère toutes les ressources du système associé. Si le flux est déjà fermé, puis d'invoquer cette méthode n'a aucun effet.
Toutefois, dans le cas général, je peux avoir des ressources qui ne implémenter AutoCloseable
(et pas Closeable
), ce qui ne garantit pas que l' close
peut être appelée plusieurs fois:
Notez que contrairement à la méthode close de java.io.Fermer, cette méthode close n'est pas nécessaire d'être idempotent. En d'autres termes, l'appel de cette méthode close plus d'une fois peut avoir certains visible effet secondaire, contrairement à la Fermer.proche qui est nécessaire pour n'avoir aucun effet si elle est appelée plus d'une fois. Cependant, les responsables de l'implémentation de cette interface sont fortement encouragés à faire leurs proches méthodes idempotent.
3)
static void printToFile3(String text, File file) {
try (FileWriter fw = new FileWriter(file)) {
BufferedWriter bw = new BufferedWriter(fw);
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
Cette version devrait être théoriquement correcte, car seule l' fw
représente une véritable ressource qui a besoin d'être nettoyé. L' bw
n'est pas elle-même une ressource, il ne délègue à l' fw
, de sorte qu'il devrait être suffisant de fermer le sous-jacent fw
.
D'autre part, la syntaxe est un peu irrégulière et aussi, Eclipse émet un avertissement, je crois que c'est une fausse alerte, mais il est encore un avertissement que l'on a à traiter:
Fuite de ressource: 'bw' est jamais fermé
Donc, quelle approche? Ou ai-je raté quelque autre idiome qui est le bon ?