web-dev-qa-db-fra.com

Try-with-resources: Dois-je lever ou intercepter les exceptions de la méthode close ()?

Veuillez me corriger si cela ne va pas: dans l'instruction Java 7 try-with-resources, toutes les exceptions levées par la méthode close() de la ressource doivent être déclarées comme levées par ma méthode ou je dois encapsuler tout l'essai dans un autre try qui intercepte toutes les exceptions levées par close().

Si c'est le cas, je dois me demander si j'en ferai un grand usage. Je ne veux certainement pas throw les exceptions levées par close(), l'appelant ne saura pas quoi faire avec ça. Et un try enveloppant un autre try juste pour gérer close() n'aurait pas l'air très élégant, du moins pour moi.

ÉDITER: Je pense que j'ai accidentellement posé deux questions, dont une en double.

Question 1. Dois-je déclarer que ma méthode lève l'exception de la méthode close() ou encapsuler l'essai avec des ressources dans un autre essai? (Pas de réponse dans le duplicata proposé.)

Question 2. Existe-t-il un moyen de fermer la ressource en silence? (Clairement un doublon, donc je retire cette phrase de la question. J'espère que cela rend la question unique et satisfaisante.)

41
John Fitzpatrick

Citation de Java Language Specification ($ 14.20.3.2) :

14.20.3.2 Essai de ressources étendu

Une instruction try-with-resources avec au moins une clause catch et/ou une clause finally est appelée une instruction try-with-resources étendue. La signification d'une instruction try-with-resources étendue:

essayez ResourceSpecification
Bloquer
Captures opt
Enfin opt

est donnée par la traduction suivante dans une instruction de base try-with-resources ( §14.20.3.1 ) imbriquée dans un try-catch ou essayez-enfin ou essayez-attraper-enfin instruction:

essayez {
Essayez ResourceSpecification
Bloquer
}
Captures opt
Enfin opt

La traduction a pour effet de placer la spécification de ressource "à l'intérieur" de l'instruction try. Cela permet à une clause catch d'une instruction try-with-resources étendue d'intercepter une exception en raison de l'initialisation ou de la fermeture automatique de toute ressource.

Donc, en gros, le wrapper est déjà implémenté

32
default locale

De le tutoriel Java

Une instruction try-with-resources peut avoir catch et finalement des blocs comme une instruction try ordinaire. Dans une instruction try-with-resources, tout catch ou finalement bloc est exécuté après la fermeture des ressources déclarées .

(c'est moi qui souligne)

Vous pouvez donc simplement faire

try (BufferedReader br =
               new BufferedReader(new FileReader(path))) {
    return br.readLine();
}
catch (IOException e) {
    // handle the exception that has been thrown by readLine() OR by close().
}
23
JB Nizet

Vous n'avez pas besoin d'envelopper le try-with-resources dans un autre bloc try-catch, vous ajoutez simplement un bloc catch:

class Foo implements AutoCloseable {
    public void close() throws Exception {
        throw new Exception();
    }
}

public class Try {
    public static void main(final String[] args) {
        try(Foo f = new Foo()) {
            System.out.println("No op!");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
7
Perception

Vous devriez pouvoir simplement ajouter la clause catch (Exception e) { } appropriée. Si vous avez besoin de faire un traitement spécial pour un spécifique, ou vous pouvez simplement attraper Exception, si vous en avez besoin beaucoup plus large.

try (Statement stmt = con.createStatement()) {
    ResultSet rs = stmt.executeQuery(query);

    while (rs.next()) {
        String coffeeName = rs.getString("COF_NAME");
        int supplierID = rs.getInt("SUP_ID");
        float price = rs.getFloat("PRICE");

        System.out.println(coffeeName + ", " + supplierID + ", " + 
                           price + ", " + sales + ", " + total);
    }
} catch (Exception e) {
    System.out.println("Exception while trying to through the queries. ", e);
}

Comme c'est Java 7, vous pouvez réellement mettre plusieurs exceptions par clause catch, ou vous pouvez simplement attraper l'exception la plus externe que vous souhaitez.

2
mjuarez