Question

Y a-t-il une différence fonctionnelle ?

Connection c = null;
try {
  c = getConnection();
  c.doStuff();
} finally {
  if (c!=null) c.close();
}

contre

Connection c = null;
c = getConnection();
c.doStuff();
try {
} finally {
  if (c!=null) c.close();
}

contre

Connection c = null;
try {
  c = getConnection();
} finally {
  if (c!=null) c.close();
}
c.doStuff();

Je sens qu'ils feront tous la même chose dans tous les cas

Était-ce utile?

La solution

Une exception qui se produit en dehors d'un try-finally le bloc est par définition un exception non-gérée.Cela étant le cas, vous n'avez aucune garantie sur la manière dont le système d'exploitation ou le moteur d'exécution le gérera.Il y a de fortes chances qu'un déroulement d'exception ne soit pas déclenché, votre code sera simplement abandonné (peut-être qu'une fin anormale le décrit mieux dans cette discussion - "fin anormale"), et votre finally le bloc ne s’exécutera jamais.

Le point de try-finally est de garantir que le nettoyage du code se produit et se produit dans le contexte correct.

Vous devez penser que le code dans le finally le bloc va toujours s'exécuter quoi qu'il arrive, et qu'il va s'exécuter une fois la méthode entière terminée, donc peu importe que l'autre code soit situé à l'intérieur ou à l'extérieur du try-finally construire, mais ce n’est pas correct.

Donc, si vous voulez des garanties d'exécution d'un comportement correct, votre premier exemple est le seul correct.

  • Dans votre premier exemple, vous acquérez et plus important encore utiliser une connexion (à une base de données, pourrait-on présumer) à l'intérieur du try bloc.Si une exception se produit dans le try bloquer, puis le finally block exécutera et fermera votre connexion.

  • Dans votre deuxième exemple, votre connexion est acquise et utilisée entièrement en dehors du try-catch construction.Si une exception se produit lors de l'utilisation de la connexion, il est probable que tout le contexte soit simplement rejeté, votre finally le bloc ne s’exécutera pas et votre connexion ne sera pas fermée.

  • Dans votre troisième exemple, finally va s'exécuter après try, mais avant tout code qui vient après le finally bloc.Vous générerez une exception en essayant d'utiliser la connexion, car la connexion a déjà été explicitement fermée.

Autres conseils

Craig a déjà abordé le problème d'exception non gérée, mais je voulais préciser.J'ai codé deux exemples (le dernier est juste mauvais parce que vous pourriez travailler avec une connexion cassée après une exception, ne le faites pas).Voici un exemple simple qui jette une exception arrayindexoutofboundsException:

class TryCatchFinally {
    static int [] array = new int[1];
    public static void main(String [] args) throws Exception {
        if (args[0].startsWith("1")) {
            version1();
        } else if (args[0].startsWith("2")) {
            version2();
        }
    }
    static int version1() {
        int r = 0;
        try {
            System.out.println("In Try.");
            return array[1];
        } catch (Exception e) {
            System.out.println("In Catch.");
        } finally {
            System.out.println("In Finally.");
        }
        System.out.println("In Return.");
        return r;
    }
    static int version2() {
        int r = array[1];
        try {
            System.out.println("In Try.");
        } catch (Exception e) {
            System.out.println("In Catch.");
        } finally {
            System.out.println("In Finally.");
        }
        System.out.println("In Return.");
        return r;
    }
}

Et voici l'exécution:

(TryCatchFinally)$ javac *.java
(TryCatchFinally)$ java TryCatchFinally 1
In Try.
In Catch.
In Finally.
In Return.
(TryCatchFinally)$ java TryCatchFinally 2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
    at TryCatchFinally.version2(TryCatchFinally.java:24)
    at TryCatchFinally.main(TryCatchFinally.java:7)
(TryCatchFinally)$

Comme vous pouvez le voir dans la première version, un gestionnaire d'exception a été enregistré car l'exception s'est produite dans le contexte d'un bloc d'essai.Dans la deuxième version, il n'y avait pas de gestionnaire d'exception enregistré et le gestionnaire d'exception par défaut a été invoqué (ce qui signifie une exception non capturée).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top